diff --git a/MAINTAINERS b/MAINTAINERS index 83f72dacc1f3..cb3d1551bfcb 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13580,12 +13580,6 @@ F: arch/arm64/boot/dts/amlogic/mesongxm.dtsi AMLOGIC SD/MMC DIRVER SUPPORT M: Nan Li -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 F: drivers/amlogic/vrtc/ + +AMLOGIC DEINTERLACE, DNR, Field Detection, VOF DRIVERS +M: Kele Bai +F: drivers/amlogic/deinterlace/* + diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts index 0b38efe11690..b269ae94e2fd 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_1g.dts @@ -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"; diff --git a/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts b/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts index e4c983aa97c9..050a17d646f1 100644 --- a/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxl_p212_2g.dts @@ -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"; diff --git a/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts b/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts index 67260c9aa4c6..5586eb06208f 100644 --- a/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts +++ b/arch/arm64/boot/dts/amlogic/gxm_q200_2g.dts @@ -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"; diff --git a/arch/arm64/boot/dts/amlogic/gxm_skt.dts b/arch/arm64/boot/dts/amlogic/gxm_skt.dts index 07ea92d0fc66..f56ee480e490 100644 --- a/arch/arm64/boot/dts/amlogic/gxm_skt.dts +++ b/arch/arm64/boot/dts/amlogic/gxm_skt.dts @@ -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"; diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig index 44ce4b7c2caa..81d090608f7c 100644 --- a/arch/arm64/configs/meson64_defconfig +++ b/arch/arm64/configs/meson64_defconfig @@ -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 diff --git a/drivers/amlogic/media/Kconfig b/drivers/amlogic/media/Kconfig index bdbdaf274ad7..51a1eeeb9d54 100644 --- a/drivers/amlogic/media/Kconfig +++ b/drivers/amlogic/media/Kconfig @@ -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 diff --git a/drivers/amlogic/media/Makefile b/drivers/amlogic/media/Makefile index b2e969f9ee49..7dc012a9e284 100644 --- a/drivers/amlogic/media/Makefile +++ b/drivers/amlogic/media/Makefile @@ -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/ diff --git a/drivers/amlogic/media/deinterlace/Kconfig b/drivers/amlogic/media/deinterlace/Kconfig new file mode 100644 index 000000000000..a2e67836e4ce --- /dev/null +++ b/drivers/amlogic/media/deinterlace/Kconfig @@ -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 diff --git a/drivers/amlogic/media/deinterlace/Makefile b/drivers/amlogic/media/deinterlace/Makefile new file mode 100644 index 000000000000..cd5be3ee736c --- /dev/null +++ b/drivers/amlogic/media/deinterlace/Makefile @@ -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/ + diff --git a/drivers/amlogic/media/deinterlace/deinterlace.c b/drivers/amlogic/media/deinterlace/deinterlace.c new file mode 100644 index 000000000000..703b948cc30e --- /dev/null +++ b/drivers/amlogic/media/deinterlace/deinterlace.c @@ -0,0 +1,7876 @@ +/* + * drivers/amlogic/media/deinterlace/deinterlace.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA +#include +#endif +#include "film_vof_soft.h" +#include "register.h" +#include "deinterlace.h" +#include "deinterlace_mtn.h" +#include "deinterlace_dbg.h" +#include +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA +#include "rdma.h" +#endif +#if defined(NEW_DI_TV) +#define ENABLE_SPIN_LOCK_ALWAYS +#endif +#ifdef DET3D +#include "detect3d.h" +#endif +#ifdef NEW_DI_V4 +#include "nr.h" +#endif + +#define RUN_DI_PROCESS_IN_IRQ + +#ifdef ENABLE_SPIN_LOCK_ALWAYS +static DEFINE_SPINLOCK(di_lock2); +#define di_lock_irqfiq_save(irq_flag, fiq_flag) \ + do { fiq_flag = 0; flags = flags; \ + spin_lock_irqsave(&di_lock2, irq_flag); \ + } while (0) + +#define di_unlock_irqfiq_restore(irq_flag, fiq_flag) + spin_unlock_irqrestore(&di_lock2, irq_flag); + +#else +#define di_lock_irqfiq_save(irq_flag, fiq_flag) \ + do { flags = irq_flag; \ + irq_flag = fiq_flag; \ + } while (0) +#define di_unlock_irqfiq_restore(irq_flag, fiq_flag) \ + do { flags = irq_flag; \ + irq_flag = fiq_flag; \ + } while (0) +#endif + +int mpeg2vdin_flag; +int mpeg2vdin_en; + +static int queue_print_flag = -1; +static bool overturn; +static bool check_start_drop_prog; +bool mcpre_en = true; + +#ifdef NEW_DI_V4 +static bool dnr_en = 1; +#endif +static unsigned int di_pre_rdma_enable; +static bool full_422_pack; +static bool tff_bff_enable; + +#define CHECK_VDIN_BUF_ERROR + +#define DEVICE_NAME "deinterlace" +#define CLASS_NAME "deinterlace" + +char *vf_get_receiver_name(const char *provider_name); + +static DEFINE_SPINLOCK(plist_lock); + +static di_dev_t *de_devp; +static dev_t di_devno; +static struct class *di_clsp; + +#define INIT_FLAG_NOT_LOAD 0x80 +static const char version_s[] = "2016-09-29a"; +static unsigned char boot_init_flag; +static int receiver_is_amvideo = 1; + +static unsigned char new_keep_last_frame_enable; +static int bypass_state = 1; +static int bypass_4K; +static int bypass_all; +static bool bypass_direct; +/*1:enable bypass pre,ei only; + * 2:debug force bypass pre,ei for post + */ +static int bypass_pre; +static int bypass_trick_mode = 1; +static int bypass_3d = 1; +static int invert_top_bot; +static int skip_top_bot;/*1or2: may affect atv when bypass di*/ + +static int post_hold_line = 17;/* for m8 1080i/50 output */ +static int force_update_post_reg = 0x10; +/* + * bit[4] + * 1 call process_fun every vsync; + * 0 call process_fun when toggle frame (early_process_fun is called) + * bit[3:0] set force_update_post_reg = 1: only update post reg in + * vsync for one time + * set force_update_post_reg = 2: always update post reg in vsync + */ +static int bypass_post; +bool post_wr_en; +unsigned int post_wr_surpport; +static int bypass_post_state; +static int vdin_source_flag; +static int update_post_reg_count = 1; +static int timeout_miss_policy; +/* 0, use di_wr_buf still; + * 1, call pre_de_done_buf_clear to clear di_wr_buf; + * 2, do nothing + */ + +static int force_width; +/* add avoid vframe put/get error */ +static int di_blocking; +/* + * bit[2]: enable bypass all when skip + * bit[1:0]: enable bypass post when skip + */ +static int di_vscale_skip_enable; + +/* 0: not surpport nr10bit, 1: surpport nr10bit */ +static unsigned int nr10bit_surpport; + +#ifdef RUN_DI_PROCESS_IN_IRQ +/* + * di_process() run in irq, + * di_reg_process(), di_unreg_process() run in kernel thread + * di_reg_process_irq(), di_unreg_process_irq() run in irq + * di_vf_put(), di_vf_peek(), di_vf_get() run in irq + * di_receiver_event_fun() run in task or irq + */ +/* + * important: + * to set input2pre, VFRAME_EVENT_PROVIDER_VFRAME_READY of + * vdin should be sent in irq + */ +#ifdef NEW_DI_V1 +#undef CHECK_DI_DONE +#else +#define CHECK_DI_DONE +#endif + +#ifdef NEW_DI_TV +static int input2pre = 1; +/*false:process progress by field; + * true: process progress by frame with 2 interlace buffer + */ +#else +static int input2pre; +#endif +static int use_2_interlace_buff; +static int input2pre_buf_miss_count; +static int input2pre_proc_miss_count; +static int input2pre_throw_count; +static int static_pic_threshold = 10; +#ifdef NEW_DI_V1 +static int input2pre_miss_policy; +/* 0, do not force pre_de_busy to 0, use di_wr_buf after de_irq happen; + * 1, force pre_de_busy to 0 and call pre_de_done_buf_clear to clear di_wr_buf + */ +#else +static int input2pre_miss_policy; +/* 0, do not force pre_de_busy to 0, use di_wr_buf after de_irq happen; + * 1, force pre_de_busy to 0 and call pre_de_done_buf_clear to clear di_wr_buf + */ +#endif +#else +#ifdef NEW_DI_TV +static int use_2_interlace_buff = 1; +/*false:process progress by field; + * bit0: process progress by frame with 2 interlace buffer + * bit1: temp add debug for 3d process FA,1:bit0 force to 1; + */ +#else +static int use_2_interlace_buff; +#endif +#endif +/* prog_proc_config, + * bit[2:1]: when two field buffers are used, + * 0 use vpp for blending , + * 1 use post_di module for blending + * 2 debug mode, bob with top field + * 3 debug mode, bot with bot field + * bit[0]: + * 0 "prog vdin" use two field buffers, + * 1 "prog vdin" use single frame buffer + * bit[4]: + * 0 "prog frame from decoder/vdin" use two field buffers, + * 1 use single frame buffer + * bit[5]: + * when two field buffers are used for decoder (bit[4] is 0): + * 1,handle prog frame as two interlace frames + * bit[6]:(bit[4] is 0,bit[5] is 0,use_2_interlace_buff is 0): 0, + * process progress frame as field,blend by post; + * 1, process progress frame as field,process by normal di + */ +static int prog_proc_config = (1 << 5) | (1 << 1) | 1; +/* + * for source include both progressive and interlace pictures, + * always use post_di module for blending + */ +#define is_handle_prog_frame_as_interlace(vframe) \ + (((prog_proc_config & 0x30) == 0x20) && \ + ((vframe->type & VIDTYPE_VIU_422) == 0)) + +static int skip_wrong_field = 1; +static int frame_count; +static int provider_vframe_level; +static int disp_frame_count; +static int start_frame_drop_count = 2; +/* static int start_frame_hold_count = 0; */ + +static int force_trig_cnt; +static int di_process_cnt; +static int video_peek_cnt; +static int force_bob_flag; +int di_vscale_skip_count; +int di_vscale_skip_count_real; +static int vpp_3d_mode; +#ifdef DET3D +bool det3d_en; +static unsigned int det3d_mode; +static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf); +#endif + +static int force_duration_0; + +static uint init_flag;/*flag for di buferr*/ +static uint mem_flag;/*flag for mem alloc*/ +static unsigned int reg_flag;/*flag for vframe reg/unreg*/ +static unsigned int unreg_cnt;/*cnt for vframe unreg*/ +static unsigned int reg_cnt;/*cnt for vframe reg*/ +static unsigned char active_flag; +static unsigned char recovery_flag; +static unsigned int force_recovery = 1; +static unsigned int force_recovery_count; +static unsigned int recovery_log_reason; +static unsigned int recovery_log_queue_idx; +static struct di_buf_s *recovery_log_di_buf; + +#define VFM_NAME "deinterlace" + +static long same_field_top_count; +static long same_field_bot_count; +static long same_w_r_canvas_count; +/* bit 0: + * 0, keep 3 buffers in pre_ready_list for checking; + * 1, keep 4 buffers in pre_ready_list for checking; + */ + +static int same_field_source_flag_th = 60; + +static int pre_hold_line = 10; +static int pre_urgent = 1; +static int post_urgent = 1; + +/*pre process speed debug */ +static int pre_process_time; +static int pre_process_time_force; +/**/ +#define USED_LOCAL_BUF_MAX 3 +static int used_local_buf_index[USED_LOCAL_BUF_MAX]; +static int used_post_buf_index = -1; + +static int di_receiver_event_fun(int type, void *data, void *arg); +static void di_uninit_buf(void); +static unsigned char is_bypass(vframe_t *vf_in); +static void log_buffer_state(unsigned char *tag); +/* static void put_get_disp_buf(void); */ + +static const +struct vframe_receiver_op_s di_vf_receiver = { + .event_cb = di_receiver_event_fun +}; + +static struct vframe_receiver_s di_vf_recv; + +static vframe_t *di_vf_peek(void *arg); +static vframe_t *di_vf_get(void *arg); +static void di_vf_put(vframe_t *vf, void *arg); +static int di_event_cb(int type, void *data, void *private_data); +static int di_vf_states(struct vframe_states *states, void *arg); +static void di_process(void); +static void di_reg_process(void); +static void di_reg_process_irq(void); +static void di_unreg_process(void); +static void di_unreg_process_irq(void); + +static const +struct vframe_operations_s deinterlace_vf_provider = { + .peek = di_vf_peek, + .get = di_vf_get, + .put = di_vf_put, + .event_cb = di_event_cb, + .vf_states = di_vf_states, +}; + +static struct vframe_provider_s di_vf_prov; + +static int di_sema_init_flag; +static struct semaphore di_sema; + +void trigger_pre_di_process(char idx) +{ + if (di_sema_init_flag == 0) + return; + + if (idx != 'p') + log_buffer_state((idx == 'i') ? "irq" : ((idx == 'p') ? + "put" : ((idx == 'r') ? "rdy" : "oth"))); + +#if (defined RUN_DI_PROCESS_IN_IRQ) + aml_write_cbus(ISA_TIMERC, 1); + /* trigger di_reg_process and di_unreg_process */ + if ((idx != 'p') && (idx != 'i')) + up(&di_sema); +#endif +} + +#define DI_PRE_INTERVAL (HZ / 100) + +static struct timer_list di_pre_timer; +static struct work_struct di_pre_work; +static unsigned int di_printk_flag; + +static void di_pre_timer_cb(unsigned long arg) +{ + struct timer_list *timer = (struct timer_list *)arg; + + schedule_work(&di_pre_work); + + timer->expires = jiffies + DI_PRE_INTERVAL; + add_timer(timer); +} + +/************For Write register**********************/ +static unsigned int di_stop_reg_flag; +static unsigned int num_di_stop_reg_addr = 4; +static unsigned int di_stop_reg_addr[4] = {0}; + +unsigned int is_need_stop_reg(unsigned int addr) +{ + int idx = 0; + + if (di_stop_reg_flag) { + for (idx = 0; idx < num_di_stop_reg_addr; idx++) { + if (addr == di_stop_reg_addr[idx]) { + pr_dbg("stop write addr: %x\n", addr); + return 1; + } + } + } + + return 0; +} + +void DI_Wr(unsigned int addr, unsigned int val) +{ + if (is_need_stop_reg(addr)) + return; + + Wr(addr, val); +} + +void DI_Wr_reg_bits(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len) +{ + if (is_need_stop_reg(adr)) + return; + + Wr_reg_bits(adr, val, start, len); +} + +void DI_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val) +{ + if (is_need_stop_reg(addr)) + return; + + VSYNC_WR_MPEG_REG(addr, val); +} + +void DI_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, unsigned int val, + unsigned int start, unsigned int len) +{ + if (is_need_stop_reg(addr)) + return; + + VSYNC_WR_MPEG_REG_BITS(addr, val, start, len); +} + +/**********************************/ + +/***************************** + * di attr management : + * enable + * mode + * reg + ******************************/ +/*config attr*/ +static ssize_t +show_config(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int pos = 0; + + return pos; +} + +static ssize_t +store_config(struct device *dev, struct device_attribute *attr, const char *buf, + size_t count); + +static void dump_state(void); +static struct queue_s *get_queue_by_idx(int idx); + +#define DI_RUN_FLAG_RUN 0 +#define DI_RUN_FLAG_PAUSE 1 +#define DI_RUN_FLAG_STEP 2 +#define DI_RUN_FLAG_STEP_DONE 3 + +static int run_flag = DI_RUN_FLAG_RUN; +static int pre_run_flag = DI_RUN_FLAG_RUN; +static int dump_state_flag; + +static ssize_t +store_dbg(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (strncmp(buf, "buf", 3) == 0) { + struct di_buf_s *di_buf_tmp = 0; + + if (kstrtoul(buf + 3, 16, (unsigned long *)&di_buf_tmp)) + return count; + dump_di_buf(di_buf_tmp); + } else if (strncmp(buf, "vframe", 6) == 0) { + vframe_t *vf = 0; + + if (kstrtoul(buf + 6, 16, (unsigned long *)&vf)) + return count; + dump_vframe(vf); + } else if (strncmp(buf, "pool", 4) == 0) { + unsigned long idx = 0; + + if (kstrtoul(buf + 4, 10, &idx)) + return count; + dump_pool(get_queue_by_idx(idx)); + } else if (strncmp(buf, "state", 4) == 0) { + dump_state(); + } else if (strncmp(buf, "prog_proc_config", 16) == 0) { + if (buf[16] == '1') + prog_proc_config = 1; + else + prog_proc_config = 0; + } else if (strncmp(buf, "init_flag", 9) == 0) { + if (buf[9] == '1') + init_flag = 1; + else + init_flag = 0; + } else if (strncmp(buf, "show_osd", 8) == 0) { + DI_Wr(VIU_OSD1_CTRL_STAT, + Rd(VIU_OSD1_CTRL_STAT) | (0xff << 12)); + } else if (strncmp(buf, "run", 3) == 0) { + /* timestamp_pcrscr_enable(1); */ + run_flag = DI_RUN_FLAG_RUN; + } else if (strncmp(buf, "pause", 5) == 0) { + /* timestamp_pcrscr_enable(0); */ + run_flag = DI_RUN_FLAG_PAUSE; + } else if (strncmp(buf, "step", 4) == 0) { + run_flag = DI_RUN_FLAG_STEP; + } else if (strncmp(buf, "prun", 4) == 0) { + pre_run_flag = DI_RUN_FLAG_RUN; + } else if (strncmp(buf, "ppause", 6) == 0) { + pre_run_flag = DI_RUN_FLAG_PAUSE; + } else if (strncmp(buf, "pstep", 5) == 0) { + pre_run_flag = DI_RUN_FLAG_STEP; + } else if (strncmp(buf, "dumpreg", 7) == 0) { + dump_di_reg(); + } else if (strncmp(buf, "robust_test", 11) == 0) { + recovery_flag = 1; + } else if (strncmp(buf, "recycle_buf", 11) == 0) { + recycle_keep_buffer(); + } else { + pr_info("DI no support cmd!!!\n"); + } + + return count; +} +#ifdef NEW_DI_V1 +static int __init di_read_canvas_reverse(char *str) +{ + unsigned char *ptr = str; + + pr_dbg("%s: bootargs is %s.\n", __func__, str); + if (strstr(ptr, "1")) { + invert_top_bot |= 0x1; + overturn = true; + } else { + invert_top_bot &= (~0x1); + overturn = false; + } + + return 0; +} +__setup("video_reverse=", di_read_canvas_reverse); +#endif +unsigned int di_debug_flag = 0x10;/* enable rdma even di bypassed */ +static unsigned char *di_log_buf; +static unsigned int di_log_wr_pos; +static unsigned int di_log_rd_pos; +static unsigned int di_log_buf_size; +static unsigned int di_printk_flag; +unsigned int di_log_flag; +static unsigned int buf_state_log_threshold = 16; +static unsigned int buf_state_log_start; +/* set to 1 by condition of "post_ready count < buf_state_log_threshold", + * reset to 0 by set buf_state_log_threshold as 0 + */ + +static DEFINE_SPINLOCK(di_print_lock); + +#define PRINT_TEMP_BUF_SIZE 128 + +int di_print_buf(char *buf, int len) +{ + unsigned long flags; + int pos; + int di_log_rd_pos_; + + if (di_log_buf_size == 0) + return 0; + + spin_lock_irqsave(&di_print_lock, flags); + di_log_rd_pos_ = di_log_rd_pos; + if (di_log_wr_pos >= di_log_rd_pos) + di_log_rd_pos_ += di_log_buf_size; + + for (pos = 0; pos < len && di_log_wr_pos < (di_log_rd_pos_ - 1); + pos++, di_log_wr_pos++) { + if (di_log_wr_pos >= di_log_buf_size) + di_log_buf[di_log_wr_pos - di_log_buf_size] = buf[pos]; + else + di_log_buf[di_log_wr_pos] = buf[pos]; + } + if (di_log_wr_pos >= di_log_buf_size) + di_log_wr_pos -= di_log_buf_size; + spin_unlock_irqrestore(&di_print_lock, flags); + return pos; +} + +/* static int log_seq = 0; */ +#if 0 +#define di_print printk +#else +int di_print(const char *fmt, ...) +{ + va_list args; + int avail = PRINT_TEMP_BUF_SIZE; + char buf[PRINT_TEMP_BUF_SIZE]; + int pos, len = 0; + + if (di_printk_flag & 1) { + if (di_log_flag & DI_LOG_PRECISE_TIMESTAMP) + pr_dbg("%u:", aml_read_cbus(ISA_TIMERE)); + va_start(args, fmt); + vprintk(fmt, args); + va_end(args); + return 0; + } + + if (di_log_buf_size == 0) + return 0; + +/* len += snprintf(buf+len, avail-len, "%d:",log_seq++); */ + if (di_log_flag & DI_LOG_TIMESTAMP) + len += snprintf(buf + len, avail - len, "%u:", + jiffies_to_msecs(jiffies_64)); + else if (di_log_flag & DI_LOG_PRECISE_TIMESTAMP) + len += snprintf(buf + len, avail - len, "%u:", + aml_read_cbus(ISA_TIMERE)); + + va_start(args, fmt); + len += vsnprintf(buf + len, avail - len, fmt, args); + va_end(args); + + if ((avail - len) <= 0) + buf[PRINT_TEMP_BUF_SIZE - 1] = '\0'; + + pos = di_print_buf(buf, len); +/* pr_dbg("di_print:%d %d\n", di_log_wr_pos, di_log_rd_pos); */ + return pos; +} +#endif + +static ssize_t read_log(char *buf) +{ + unsigned long flags; + ssize_t read_size = 0; + + if (di_log_buf_size == 0) + return 0; +/* pr_dbg("show_log:%d %d\n", di_log_wr_pos, di_log_rd_pos); */ + spin_lock_irqsave(&di_print_lock, flags); + if (di_log_rd_pos < di_log_wr_pos) + read_size = di_log_wr_pos - di_log_rd_pos; + + else if (di_log_rd_pos > di_log_wr_pos) + read_size = di_log_buf_size - di_log_rd_pos; + + if (read_size > PAGE_SIZE) + read_size = PAGE_SIZE; + if (read_size > 0) + memcpy(buf, di_log_buf + di_log_rd_pos, read_size); + + di_log_rd_pos += read_size; + if (di_log_rd_pos >= di_log_buf_size) + di_log_rd_pos = 0; + spin_unlock_irqrestore(&di_print_lock, flags); + return read_size; +} + +static ssize_t +show_log(struct device *dev, struct device_attribute *attr, char *buf) +{ + return read_log(buf); +} + +static ssize_t +store_log(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long flags, tmp; + + if (strncmp(buf, "bufsize", 7) == 0) { + if (kstrtoul(buf + 7, 10, &tmp)) + return count; + spin_lock_irqsave(&di_print_lock, flags); + kfree(di_log_buf); + di_log_buf = NULL; + di_log_buf_size = 0; + di_log_rd_pos = 0; + di_log_wr_pos = 0; + if (tmp >= 1024) { + di_log_buf_size = 0; + di_log_rd_pos = 0; + di_log_wr_pos = 0; + di_log_buf = kmalloc(tmp, GFP_KERNEL); + if (di_log_buf) + di_log_buf_size = tmp; + } + spin_unlock_irqrestore(&di_print_lock, flags); + pr_dbg("di_store:set bufsize tmp %lu %u\n", + tmp, di_log_buf_size); + } else if (strncmp(buf, "printk", 6) == 0) { + if (kstrtoul(buf + 6, 10, &tmp)) + return count; + di_printk_flag = tmp; + } else { + di_print("%s", buf); + } + return 16; +} + +struct di_status_s { + char *name; + uint *status; +}; +#define di_status_t struct di_status_s +di_status_t di_status[] = { + { "active", &init_flag }, + { "", NULL } +}; + +static ssize_t +show_status(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i = 0; + int len = 0; + + di_print("%s\n", __func__); + for (i = 0; di_status[i].status; i++) + len += sprintf(buf + len, "%s=%08x\n", di_status[i].name, + *(di_status[i].status)); + return len; +} + +static ssize_t +show_vframe_status(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret = 0; + struct vframe_states states; + struct vframe_provider_s *vfp; + + vfp = vf_get_provider(VFM_NAME); + if (vfp && vfp->ops && vfp->ops->vf_states) + ret = vfp->ops->vf_states(&states, vfp->op_arg); + + if (ret == 0) { + ret += sprintf(buf + ret, "vframe_pool_size=%d\n", + states.vf_pool_size); + ret += sprintf(buf + ret, "vframe buf_free_num=%d\n", + states.buf_free_num); + ret += sprintf(buf + ret, "vframe buf_recycle_num=%d\n", + states.buf_recycle_num); + ret += sprintf(buf + ret, "vframe buf_avail_num=%d\n", + states.buf_avail_num); + } else { + ret += sprintf(buf + ret, "vframe no states\n"); + } + + return ret; +} + +struct pd_param_s { + char *name; + int *addr; +}; +struct FlmDectRes dectres; +struct sFlmSftPar pd_param; +static struct pd_param_s pd_params[] = { + { "sFrmDifAvgRat", + &(pd_param.sFrmDifAvgRat)}, + { "sFrmDifLgTDif", + &(pd_param.sFrmDifLgTDif) }, + { "sF32StpWgt01", + &(pd_param.sF32StpWgt01) }, + { "sF32StpWgt02", + &(pd_param.sF32StpWgt02) }, + { "sF32DifLgRat", + &(pd_param.sF32DifLgRat) }, + { "sFlm2MinAlpha", + &(pd_param.sFlm2MinAlpha) }, + { "sFlm2MinBelta", + &(pd_param.sFlm2MinBelta) }, + { "sFlm20ftAlpha", + &(pd_param.sFlm20ftAlpha) }, + { "sFlm2LgDifThd", + &(pd_param.sFlm2LgDifThd) }, + { "sFlm2LgFlgThd", + &(pd_param.sFlm2LgFlgThd) }, + { "sF32Dif01A1", + &(pd_param.sF32Dif01A1) }, + { "sF32Dif01T1", + &(pd_param.sF32Dif01T1) }, + { "sF32Dif01A2", + &(pd_param.sF32Dif01A2) }, + { "sF32Dif01T2", + &(pd_param.sF32Dif01T2) }, + { "rCmbRwMinCt0", + &(pd_param.rCmbRwMinCt0) }, + { "rCmbRwMinCt1", + &(pd_param.rCmbRwMinCt1) }, + { "mPstDlyPre", + &(pd_param.mPstDlyPre) }, + { "mNxtDlySft", + &(pd_param.mNxtDlySft) }, + { "sF32Dif02M0", + &(pd_param.sF32Dif02M0) }, /* mpeg-4096, cvbs-8192 */ + { "sF32Dif02M1", + &(pd_param.sF32Dif02M1) }, /* mpeg-4096, cvbs-8192 */ + { "", NULL } +}; + +static ssize_t pd_param_store(struct device *dev, + struct device_attribute *attr, const char *buff, + size_t count) +{ + int i = 0; + int value = 0; + int rc = 0; + char *parm[2] = { NULL }, *buf_orig; + + buf_orig = kstrdup(buff, GFP_KERNEL); + parse_cmd_params(buf_orig, (char **)(&parm)); + for (i = 0; pd_params[i].addr; i++) { + if (!strcmp(parm[0], pd_params[i].name)) { + rc = kstrtoint(parm[1], 10, &value); + *(pd_params[i].addr) = value; + pr_dbg("%s=%d.\n", pd_params[i].name, value); + } + } + + return count; +} + +static ssize_t pd_param_show(struct device *dev, + struct device_attribute *attr, char *buff) +{ + ssize_t len = 0; + int i = 0; + + for (i = 0; pd_params[i].addr; i++) + len += sprintf(buff + len, "%s=%d.\n", + pd_params[i].name, *pd_params[i].addr); + + len += sprintf(buff + len, "\npulldown detection result:\n"); + len += sprintf(buff + len, "rCmb32Spcl=%u.\n", dectres.rCmb32Spcl); + len += sprintf(buff + len, "rPstCYWnd0 s=%u.\n", dectres.rPstCYWnd0[0]); + len += sprintf(buff + len, "rPstCYWnd0 e=%u.\n", dectres.rPstCYWnd0[1]); + len += sprintf(buff + len, "rPstCYWnd0 b=%u.\n", dectres.rPstCYWnd0[2]); + + len += sprintf(buff + len, "rPstCYWnd1 s=%u.\n", dectres.rPstCYWnd1[0]); + len += sprintf(buff + len, "rPstCYWnd1 e=%u.\n", dectres.rPstCYWnd1[1]); + len += sprintf(buff + len, "rPstCYWnd1 b=%u.\n", dectres.rPstCYWnd1[2]); + + len += sprintf(buff + len, "rPstCYWnd2 s=%u.\n", dectres.rPstCYWnd2[0]); + len += sprintf(buff + len, "rPstCYWnd2 e=%u.\n", dectres.rPstCYWnd2[1]); + len += sprintf(buff + len, "rPstCYWnd2 b=%u.\n", dectres.rPstCYWnd2[2]); + + len += sprintf(buff + len, "rPstCYWnd3 s=%u.\n", dectres.rPstCYWnd3[0]); + len += sprintf(buff + len, "rPstCYWnd3 e=%u.\n", dectres.rPstCYWnd3[1]); + len += sprintf(buff + len, "rPstCYWnd3 b=%u.\n", dectres.rPstCYWnd3[2]); + + len += sprintf(buff + len, "rPstCYWnd4 s=%u.\n", dectres.rPstCYWnd4[0]); + len += sprintf(buff + len, "rPstCYWnd4 e=%u.\n", dectres.rPstCYWnd4[1]); + len += sprintf(buff + len, "rPstCYWnd4 b=%u.\n", dectres.rPstCYWnd4[2]); + + len += sprintf(buff + len, "rFlmPstGCm=%u.\n", dectres.rFlmPstGCm); + len += sprintf(buff + len, "rFlmSltPre=%u.\n", dectres.rFlmSltPre); + len += sprintf(buff + len, "rFlmPstMod=%d.\n", dectres.rFlmPstMod); + len += sprintf(buff + len, "rF22Flag=%d.\n", dectres.rF22Flag); + return len; +} + +static ssize_t show_tvp_region(struct device *dev, + struct device_attribute *attr, char *buff) +{ + ssize_t len = 0; + + len = sprintf(buff, "segment DI:%lx - %lx (size:0x%x)\n", + de_devp->mem_start, + de_devp->mem_start + de_devp->mem_size - 1, + de_devp->mem_size); + return len; +} + + +static DEVICE_ATTR(pd_param, 0664, pd_param_show, pd_param_store); + +static ssize_t store_dump_mem(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len); +static DEVICE_ATTR(config, 0640, show_config, store_config); +static DEVICE_ATTR(debug, 0200, NULL, store_dbg); +static DEVICE_ATTR(dump_pic, 0200, NULL, store_dump_mem); +static DEVICE_ATTR(log, 0640, show_log, store_log); +static DEVICE_ATTR(status, 0444, show_status, NULL); +static DEVICE_ATTR(provider_vframe_status, 0444, show_vframe_status, NULL); +static DEVICE_ATTR(tvp_region, 0444, show_tvp_region, NULL); +/*************************** + * di buffer management + ***************************/ +#define MAX_IN_BUF_NUM 20 +#define MAX_LOCAL_BUF_NUM 12 +#define MAX_POST_BUF_NUM 16 + +#define VFRAME_TYPE_IN 1 +#define VFRAME_TYPE_LOCAL 2 +#define VFRAME_TYPE_POST 3 +#define VFRAME_TYPE_NUM 3 + +static char *vframe_type_name[] = { + "", "di_buf_in", "di_buf_loc", "di_buf_post" +}; + +#if defined(CONFIG_AM_DEINTERLACE_SD_ONLY) +static unsigned int default_width = 720; +static unsigned int default_height = 576; +#else +static unsigned int default_width = 1920; +static unsigned int default_height = 1080; +#endif +static int local_buf_num; + +/* + * progressive frame process type config: + * 0, process by field; + * 1, process by frame (only valid for vdin source whose + * width/height does not change) + */ +static vframe_t *vframe_in[MAX_IN_BUF_NUM]; +static vframe_t vframe_in_dup[MAX_IN_BUF_NUM]; +static vframe_t vframe_local[MAX_LOCAL_BUF_NUM * 2]; +static vframe_t vframe_post[MAX_POST_BUF_NUM]; +static struct di_buf_s *cur_post_ready_di_buf; + +static struct di_buf_s di_buf_local[MAX_LOCAL_BUF_NUM * 2]; +static struct di_buf_s di_buf_in[MAX_IN_BUF_NUM]; +static struct di_buf_s di_buf_post[MAX_POST_BUF_NUM]; + +/* + * all buffers are in + * 1) list of local_free_list,in_free_list,pre_ready_list,recycle_list + * 2) di_pre_stru.di_inp_buf + * 3) di_pre_stru.di_wr_buf + * 4) cur_post_ready_di_buf + * 5) (struct di_buf_s*)(vframe->private_data)->di_buf[] + * + * 6) post_free_list_head + * 8) (struct di_buf_s*)(vframe->private_data) + */ +#define QUEUE_LOCAL_FREE 0 +#define QUEUE_IN_FREE 1 +#define QUEUE_PRE_READY 2 +#define QUEUE_POST_FREE 3 +#define QUEUE_POST_READY 4 +#define QUEUE_RECYCLE 5 +#define QUEUE_DISPLAY 6 +#define QUEUE_TMP 7 +#define QUEUE_POST_DOING 8 +#define QUEUE_NUM 9 + +#define queue_t struct queue_s +static queue_t queue[QUEUE_NUM]; + +static struct queue_s *get_queue_by_idx(int idx) +{ + if (idx < QUEUE_NUM) + return &(queue[idx]); + else + return NULL; +} + +struct di_buf_pool_s { + struct di_buf_s *di_buf_ptr; + unsigned int size; +} di_buf_pool[VFRAME_TYPE_NUM]; + +#define queue_for_each_entry(di_buf, ptm, queue_idx, list) \ + for (itmp = 0; ((di_buf = get_di_buf(queue_idx, &itmp)) != NULL); ) + +static void queue_init(int local_buffer_num) +{ + int i, j; + + for (i = 0; i < QUEUE_NUM; i++) { + queue_t *q = &queue[i]; + + for (j = 0; j < MAX_QUEUE_POOL_SIZE; j++) + q->pool[j] = 0; + + q->in_idx = 0; + q->out_idx = 0; + q->num = 0; + q->type = 0; + if ((i == QUEUE_RECYCLE) || + (i == QUEUE_DISPLAY) || + (i == QUEUE_TMP) || + (i == QUEUE_POST_DOING)) + q->type = 1; + + if ((i == QUEUE_LOCAL_FREE) && use_2_interlace_buff) + q->type = 2; + } + if (local_buffer_num > 0) { + di_buf_pool[VFRAME_TYPE_IN - 1].di_buf_ptr = &di_buf_in[0]; + di_buf_pool[VFRAME_TYPE_IN - 1].size = MAX_IN_BUF_NUM; + + di_buf_pool[VFRAME_TYPE_LOCAL-1].di_buf_ptr = &di_buf_local[0]; + di_buf_pool[VFRAME_TYPE_LOCAL - 1].size = local_buffer_num; + + di_buf_pool[VFRAME_TYPE_POST - 1].di_buf_ptr = &di_buf_post[0]; + di_buf_pool[VFRAME_TYPE_POST - 1].size = MAX_POST_BUF_NUM; + } +} + +static struct di_buf_s *get_di_buf(int queue_idx, int *start_pos) +{ + queue_t *q = &(queue[queue_idx]); + int idx = 0; + unsigned int pool_idx, di_buf_idx; + struct di_buf_s *di_buf = NULL; + int start_pos_init = *start_pos; + + if (di_log_flag & DI_LOG_QUEUE) + di_print("%s:<%d:%d,%d,%d> %d\n", __func__, queue_idx, + q->num, q->in_idx, q->out_idx, *start_pos); + + if (q->type == 0) { + if ((*start_pos) < q->num) { + idx = q->out_idx + (*start_pos); + if (idx >= MAX_QUEUE_POOL_SIZE) + idx -= MAX_QUEUE_POOL_SIZE; + + (*start_pos)++; + } else { + idx = MAX_QUEUE_POOL_SIZE; + } + } else if ((q->type == 1) || (q->type == 2)) { + for (idx = (*start_pos); idx < MAX_QUEUE_POOL_SIZE; idx++) { + if (q->pool[idx] != 0) { + *start_pos = idx + 1; + break; + } + } + } + if (idx < MAX_QUEUE_POOL_SIZE) { + pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1; + di_buf_idx = q->pool[idx] & 0xff; + if (pool_idx < VFRAME_TYPE_NUM) { + if (di_buf_idx < di_buf_pool[pool_idx].size) + di_buf = + &(di_buf_pool[pool_idx].di_buf_ptr[ + di_buf_idx]); + } + } + + if ((di_buf) && ((((pool_idx + 1) << 8) | di_buf_idx) + != ((di_buf->type << 8) | (di_buf->index)))) { + pr_dbg("%s: Error (%x,%x)\n", __func__, + (((pool_idx + 1) << 8) | di_buf_idx), + ((di_buf->type << 8) | (di_buf->index))); + if (recovery_flag == 0) { + recovery_log_reason = 1; + recovery_log_queue_idx = (start_pos_init<<8)|queue_idx; + recovery_log_di_buf = di_buf; + } + recovery_flag++; + di_buf = NULL; + } + + if (di_log_flag & DI_LOG_QUEUE) { + if (di_buf) + di_print("%s: %x(%d,%d)\n", __func__, di_buf, + pool_idx, di_buf_idx); + else + di_print("%s: %x\n", __func__, di_buf); + } + + return di_buf; +} + + +static struct di_buf_s *get_di_buf_head(int queue_idx) +{ + queue_t *q = &(queue[queue_idx]); + int idx; + unsigned int pool_idx, di_buf_idx; + struct di_buf_s *di_buf = NULL; + + if (di_log_flag & DI_LOG_QUEUE) + di_print("%s:<%d:%d,%d,%d>\n", __func__, queue_idx, + q->num, q->in_idx, q->out_idx); + + if (q->num > 0) { + if (q->type == 0) { + idx = q->out_idx; + } else { + for (idx = 0; idx < MAX_QUEUE_POOL_SIZE; idx++) + if (q->pool[idx] != 0) + break; + } + if (idx < MAX_QUEUE_POOL_SIZE) { + pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1; + di_buf_idx = q->pool[idx] & 0xff; + if (pool_idx < VFRAME_TYPE_NUM) { + if (di_buf_idx < di_buf_pool[pool_idx].size) + di_buf = &(di_buf_pool[pool_idx]. + di_buf_ptr[di_buf_idx]); + } + } + } + + if ((di_buf) && ((((pool_idx + 1) << 8) | di_buf_idx) != + ((di_buf->type << 8) | (di_buf->index)))) { + + pr_dbg("%s: Error (%x,%x)\n", __func__, + (((pool_idx + 1) << 8) | di_buf_idx), + ((di_buf->type << 8) | (di_buf->index))); + + if (recovery_flag == 0) { + recovery_log_reason = 2; + recovery_log_queue_idx = queue_idx; + recovery_log_di_buf = di_buf; + } + recovery_flag++; + di_buf = NULL; + } + + if (di_log_flag & DI_LOG_QUEUE) { + if (di_buf) + di_print("%s: %x(%d,%d)\n", __func__, di_buf, + pool_idx, di_buf_idx); + else + di_print("%s: %x\n", __func__, di_buf); + } + + return di_buf; +} + +static void queue_out(struct di_buf_s *di_buf) +{ + int i; + queue_t *q; + + if (di_buf == NULL) { + + pr_dbg("%s:Error\n", __func__); + + if (recovery_flag == 0) + recovery_log_reason = 3; + + recovery_flag++; + return; + } + if (di_buf->queue_index >= 0 && di_buf->queue_index < QUEUE_NUM) { + q = &(queue[di_buf->queue_index]); + + if (di_log_flag & DI_LOG_QUEUE) + di_print("%s:<%d:%d,%d,%d> %x\n", __func__, + di_buf->queue_index, q->num, q->in_idx, + q->out_idx, di_buf); + + if (q->num > 0) { + if (q->type == 0) { + if (q->pool[q->out_idx] == + ((di_buf->type << 8) | (di_buf->index))) { + q->num--; + q->pool[q->out_idx] = 0; + q->out_idx++; + if (q->out_idx >= MAX_QUEUE_POOL_SIZE) + q->out_idx = 0; + di_buf->queue_index = -1; + } else { + + pr_dbg( + "%s: Error (%d, %x,%x)\n", + __func__, + di_buf->queue_index, + q->pool[q->out_idx], + ((di_buf->type << 8) | + (di_buf->index))); + + if (recovery_flag == 0) { + recovery_log_reason = 4; + recovery_log_queue_idx = + di_buf->queue_index; + recovery_log_di_buf = di_buf; + } + recovery_flag++; + } + } else if (q->type == 1) { + int pool_val = + (di_buf->type << 8) | (di_buf->index); + for (i = 0; i < MAX_QUEUE_POOL_SIZE; i++) { + if (q->pool[i] == pool_val) { + q->num--; + q->pool[i] = 0; + di_buf->queue_index = -1; + break; + } + } + if (i == MAX_QUEUE_POOL_SIZE) { + + pr_dbg("%s: Error\n", __func__); + + if (recovery_flag == 0) { + recovery_log_reason = 5; + recovery_log_queue_idx = + di_buf->queue_index; + recovery_log_di_buf = di_buf; + } + recovery_flag++; + } + } else if (q->type == 2) { + int pool_val = + (di_buf->type << 8) | (di_buf->index); + if ((di_buf->index < MAX_QUEUE_POOL_SIZE) && + (q->pool[di_buf->index] == pool_val)) { + q->num--; + q->pool[di_buf->index] = 0; + di_buf->queue_index = -1; + } else { + + pr_dbg("%s: Error\n", __func__); + + if (recovery_flag == 0) { + recovery_log_reason = 5; + recovery_log_queue_idx = + di_buf->queue_index; + recovery_log_di_buf = di_buf; + } + recovery_flag++; + } + } + } + } else { + + pr_dbg("%s: Error, queue_index %d is not right\n", + __func__, di_buf->queue_index); + + if (recovery_flag == 0) { + recovery_log_reason = 6; + recovery_log_queue_idx = 0; + recovery_log_di_buf = di_buf; + } + recovery_flag++; + } + + if (di_log_flag & DI_LOG_QUEUE) + di_print("%s done\n", __func__); + +} + +static void queue_in(struct di_buf_s *di_buf, int queue_idx) +{ + queue_t *q = NULL; + + if (di_buf == NULL) { + pr_dbg("%s:Error\n", __func__); + if (recovery_flag == 0) { + recovery_log_reason = 7; + recovery_log_queue_idx = queue_idx; + recovery_log_di_buf = di_buf; + } + recovery_flag++; + return; + } + if (di_buf->queue_index != -1) { + pr_dbg("%s:%s[%d] Error, queue_index(%d) is not -1\n", + __func__, vframe_type_name[di_buf->type], + di_buf->index, di_buf->queue_index); + if (recovery_flag == 0) { + recovery_log_reason = 8; + recovery_log_queue_idx = queue_idx; + recovery_log_di_buf = di_buf; + } + recovery_flag++; + return; + } + q = &(queue[queue_idx]); + if (di_log_flag & DI_LOG_QUEUE) + di_print("%s:<%d:%d,%d,%d> %x\n", __func__, queue_idx, + q->num, q->in_idx, q->out_idx, di_buf); + + if (q->type == 0) { + q->pool[q->in_idx] = (di_buf->type << 8) | (di_buf->index); + di_buf->queue_index = queue_idx; + q->in_idx++; + if (q->in_idx >= MAX_QUEUE_POOL_SIZE) + q->in_idx = 0; + + q->num++; + } else if (q->type == 1) { + int i; + + for (i = 0; i < MAX_QUEUE_POOL_SIZE; i++) { + if (q->pool[i] == 0) { + q->pool[i] = (di_buf->type<<8)|(di_buf->index); + di_buf->queue_index = queue_idx; + q->num++; + break; + } + } + if (i == MAX_QUEUE_POOL_SIZE) { + pr_dbg("%s: Error\n", __func__); + if (recovery_flag == 0) { + recovery_log_reason = 9; + recovery_log_queue_idx = queue_idx; + } + recovery_flag++; + } + } else if (q->type == 2) { + if ((di_buf->index < MAX_QUEUE_POOL_SIZE) && + (q->pool[di_buf->index] == 0)) { + q->pool[di_buf->index] = + (di_buf->type << 8) | (di_buf->index); + di_buf->queue_index = queue_idx; + q->num++; + } else { + pr_dbg("%s: Error\n", __func__); + if (recovery_flag == 0) { + recovery_log_reason = 9; + recovery_log_queue_idx = queue_idx; + } + recovery_flag++; + } + } + + if (di_log_flag & DI_LOG_QUEUE) + di_print("%s done\n", __func__); +} + +static int list_count(int queue_idx) +{ + return queue[queue_idx].num; +} + +static bool queue_empty(int queue_idx) +{ + bool ret = (queue[queue_idx].num == 0); + + return ret; +} + +static bool is_in_queue(struct di_buf_s *di_buf, int queue_idx) +{ + bool ret = 0; + struct di_buf_s *p = NULL; + int itmp; + unsigned int overflow_cnt; + + overflow_cnt = 0; + if ((di_buf == NULL) || (queue_idx < 0) || (queue_idx >= QUEUE_NUM)) { + ret = 0; + di_print("%s: not in queue:%d!!!\n", __func__, queue_idx); + return ret; + } + queue_for_each_entry(p, ptmp, queue_idx, list) { + if (p == di_buf) { + ret = 1; + break; + } + if (overflow_cnt++ > MAX_QUEUE_POOL_SIZE) { + ret = 0; + di_print("%s: overflow_cnt!!!\n", __func__); + break; + } + } + return ret; +} + +static struct di_pre_stru_s di_pre_stru; + +static struct di_post_stru_s di_post_stru; + + +#ifdef NEW_DI_V1 +static ssize_t +store_dump_mem(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len) +{ + unsigned int n = 0, canvas_w = 0, canvas_h = 0; + unsigned long nr_size = 0; + struct di_buf_s *di_buf; + char *buf_orig, *ps, *token; + char *parm[3] = { NULL }; + char delim1[2] = " "; + char delim2[2] = "\n"; + struct file *filp = NULL; + loff_t pos = 0; + void *buff = NULL; + mm_segment_t old_fs; + + if (!buf) + return len; + buf_orig = kstrdup(buf, GFP_KERNEL); + ps = buf_orig; + strcat(delim1, delim2); + while (1) { + token = strsep(&ps, delim1); + if (token == NULL) + break; + if (*token == '\0') + continue; + parm[n++] = token; + } + if (strcmp(parm[0], "capture") == 0) + di_buf = di_pre_stru.di_mem_buf_dup_p; + else if (strcmp(parm[0], "capture_post") == 0) + di_buf = di_post_stru.cur_post_buf; + else { + pr_err("wrong dump cmd\n"); + return len; + } + if (parm[1] != NULL) { + if (unlikely(di_buf == NULL)) + return len; + } + canvas_w = di_buf->canvas_width[NR_CANVAS]; + canvas_h = di_buf->canvas_height; + nr_size = canvas_w * canvas_h * 2; + old_fs = get_fs(); + set_fs(KERNEL_DS); +/* pr_dbg("dump path =%s\n",dump_path); */ + filp = filp_open(parm[1], O_RDWR | O_CREAT, 0666); + if (IS_ERR(filp)) { + pr_err("create %s error.\n", parm[1]); + return len; + } + dump_state_flag = 1; + if (de_devp->flags && DI_MAP_FLAG) + buff = phys_to_virt(di_buf->nr_adr); + else + buff = ioremap(di_buf->nr_adr, nr_size); + if (buff == NULL) + pr_err("%s: ioremap error.\n", __func__); + vfs_write(filp, buff, nr_size, &pos); +/* pr_dbg("di_chan2_buf_dup_p:\n nr:%u,mtn:%u,cnt:%u\n", + * di_pre_stru.di_chan2_buf_dup_p->nr_adr, + * di_pre_stru.di_chan2_buf_dup_p->mtn_adr, + * di_pre_stru.di_chan2_buf_dup_p->cnt_adr); + * pr_dbg("di_inp_buf:\n nr:%u,mtn:%u,cnt:%u\n", + * di_pre_stru.di_inp_buf->nr_adr, + * di_pre_stru.di_inp_buf->mtn_adr, + * di_pre_stru.di_inp_buf->cnt_adr); + * pr_dbg("di_wr_buf:\n nr:%u,mtn:%u,cnt:%u\n", + * di_pre_stru.di_wr_buf->nr_adr, + * di_pre_stru.di_wr_buf->mtn_adr, + * di_pre_stru.di_wr_buf->cnt_adr); + * pr_dbg("di_mem_buf_dup_p:\n nr:%u,mtn:%u,cnt:%u\n", + * di_pre_stru.di_mem_buf_dup_p->nr_adr, + * di_pre_stru.di_mem_buf_dup_p->mtn_adr, + * di_pre_stru.di_mem_buf_dup_p->cnt_adr); + * pr_dbg("di_mem_start=%u\n",di_mem_start); + */ + vfs_fsync(filp, 0); + if (!(de_devp->flags & DI_MAP_FLAG)) + iounmap(buff); + dump_state_flag = 0; + filp_close(filp, NULL); + set_fs(old_fs); + pr_info("write buffer %d to %s.\n", di_buf->seq, parm[1]); + return len; +} +#endif + +#define is_from_vdin(vframe) (vframe->type & VIDTYPE_VIU_422) +static void recycle_vframe_type_pre(struct di_buf_s *di_buf); +static void recycle_vframe_type_post(struct di_buf_s *di_buf); +#ifdef DI_BUFFER_DEBUG +static void +recycle_vframe_type_post_print(struct di_buf_s *di_buf, + const char *func, + const int line); +#endif + +static void dis2_di(void) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + + init_flag = 0; + di_lock_irqfiq_save(irq_flag2, fiq_flag); +/* vf_unreg_provider(&di_vf_prov); */ + vf_light_unreg_provider(&di_vf_prov); + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + reg_flag = 0; + spin_lock_irqsave(&plist_lock, flags); + di_lock_irqfiq_save(irq_flag2, fiq_flag); + if (di_pre_stru.di_inp_buf) { + if (vframe_in[di_pre_stru.di_inp_buf->index]) { + vf_put( + vframe_in[di_pre_stru.di_inp_buf->index], + VFM_NAME); + vframe_in[di_pre_stru.di_inp_buf->index] = NULL; + vf_notify_provider( + VFM_NAME, VFRAME_EVENT_RECEIVER_PUT, NULL); + } +/* list_add_tail( + * &(di_pre_stru.di_inp_buf->list), &in_free_list_head); + */ + di_pre_stru.di_inp_buf->invert_top_bot_flag = 0; + queue_in(di_pre_stru.di_inp_buf, QUEUE_IN_FREE); + di_pre_stru.di_inp_buf = NULL; + } + di_uninit_buf(); + di_set_power_control(0, 0); + if (get_blackout_policy()) { + di_set_power_control(1, 0); + DI_Wr(DI_CLKG_CTRL, 0x2); + } + + if (post_wr_en && post_wr_surpport) { + diwr_set_power_control(0); + #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + enable_rdma(1); + #endif + } + + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + spin_unlock_irqrestore(&plist_lock, flags); +} + +static ssize_t +store_config(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + if (strncmp(buf, "disable", 7) == 0) { + + di_print("%s: disable\n", __func__); + + if (init_flag && mem_flag) { + di_pre_stru.disable_req_flag = 1; + provider_vframe_level = 0; + + trigger_pre_di_process(TRIGGER_PRE_BY_DEBUG_DISABLE); + while (di_pre_stru.disable_req_flag) + usleep_range(1000, 1001); + } + } else if (strncmp(buf, "dis2", 4) == 0) { + dis2_di(); + } + return count; +} + +static unsigned char is_progressive(vframe_t *vframe) +{ + unsigned char ret = 0; + + ret = ((vframe->type & VIDTYPE_TYPEMASK) == VIDTYPE_PROGRESSIVE); + return ret; +} + +static unsigned char is_source_change(vframe_t *vframe) +{ +#define VFRAME_FORMAT_MASK \ + (VIDTYPE_VIU_422 | VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_444 | \ + VIDTYPE_MVC) + if ((di_pre_stru.cur_width != vframe->width) || + (di_pre_stru.cur_height != vframe->height) || + (((di_pre_stru.cur_inp_type & VFRAME_FORMAT_MASK) != + (vframe->type & VFRAME_FORMAT_MASK)) && + (!is_handle_prog_frame_as_interlace(vframe))) || + (di_pre_stru.cur_source_type != vframe->source_type)) { + /* video format changed */ + return 1; + } else if ( + ((di_pre_stru.cur_prog_flag != is_progressive(vframe)) && + (!is_handle_prog_frame_as_interlace(vframe))) || + ((di_pre_stru.cur_inp_type & VIDTYPE_VIU_FIELD) != + (vframe->type & VIDTYPE_VIU_FIELD)) + ) { + /* just scan mode changed */ + if (!di_pre_stru.force_interlace) + pr_dbg("DI I<->P.\n"); + return 2; + } + return 0; +} +/* + * static unsigned char is_vframe_type_change(vframe_t* vframe) + * { + * if( + * (di_pre_stru.cur_prog_flag!=is_progressive(vframe))|| + * ((di_pre_stru.cur_inp_type&VFRAME_FORMAT_MASK)!= + * (vframe->type&VFRAME_FORMAT_MASK)) + * ) + * return 1; + * + * return 0; + * } + */ +static int trick_mode; +static unsigned char is_bypass(vframe_t *vf_in) +{ + unsigned int vtype = 0; + int ret = 0; + + if (di_debug_flag & 0x10000) /* for debugging */ + return (di_debug_flag >> 17) & 0x1; + + if (bypass_all) + return 1; + if (di_pre_stru.cur_prog_flag && + ( + (di_pre_stru.cur_width > 1920) || (di_pre_stru.cur_height > 1080) + || (di_pre_stru.cur_inp_type & VIDTYPE_VIU_444)) + ) + return 1; + + if ((di_pre_stru.cur_width < 16) || (di_pre_stru.cur_height < 16)) + return 1; + + if (di_pre_stru.cur_inp_type & VIDTYPE_MVC) + return 1; + + if (di_pre_stru.cur_source_type == VFRAME_SOURCE_TYPE_PPMGR) + return 1; + + if (((bypass_trick_mode) && + (new_keep_last_frame_enable == 0)) || (bypass_trick_mode & 0x2)) { + int trick_mode_fffb = 0; + int trick_mode_i = 0; + + if (bypass_trick_mode&0x1) + query_video_status(0, &trick_mode_fffb); + if (bypass_trick_mode&0x2) + query_video_status(1, &trick_mode_i); + trick_mode = trick_mode_fffb | (trick_mode_i << 1); + if (trick_mode) + return 1; + } + + if (bypass_3d && + (di_pre_stru.source_trans_fmt != 0)) + return 1; + +/*prot is conflict with di post*/ + if (vf_in && vf_in->video_angle) + return 1; + if (vf_in && (vf_in->type & VIDTYPE_PIC)) + return 1; + + if (vf_in && (vf_in->type & VIDTYPE_COMPRESS)) + return 1; + if ((di_vscale_skip_enable & 0x4) && vf_in) { + /*backup vtype,set type as progressive*/ + vtype = vf_in->type; + vf_in->type &= (~VIDTYPE_TYPEMASK); + vf_in->type |= VIDTYPE_VIU_422; + ret = get_current_vscale_skip_count(vf_in); + di_vscale_skip_count = (ret&0xff); + vpp_3d_mode = ((ret>>8)&0xff); + vf_in->type = vtype; + if (di_vscale_skip_count > 0 || + (vpp_3d_mode + #ifdef DET3D + && (!det3d_en) + #endif + ) + ) + return 1; + } + + return 0; +} + +static unsigned char is_bypass_post(void) +{ + if (di_debug_flag & 0x40000) /* for debugging */ + return (di_debug_flag >> 19) & 0x1; + + /*prot is conflict with di post*/ + if (di_pre_stru.orientation) + return 1; + if (bypass_post) + return 1; + + +#ifdef DET3D + if (di_pre_stru.vframe_interleave_flag != 0) + return 1; + +#endif + return 0; +} + +#ifdef RUN_DI_PROCESS_IN_IRQ +static unsigned char is_input2pre(void) +{ + if (input2pre +#ifdef NEW_DI_V3 + && di_pre_stru.cur_prog_flag +#endif + && vdin_source_flag + && (bypass_state == 0)) + return 1; + + return 0; +} +#endif + +#ifdef DI_USE_FIXED_CANVAS_IDX +static int di_post_idx[2][6]; +static int di_pre_idx[2][10]; +static int di_get_canvas(void) +{ + int pre_num = 7, post_num = 6, i = 0; + + if (mcpre_en) { + /* mem/chan2/nr/mtn/contrd/contrd2/ + * contw/mcinfrd/mcinfow/mcvecw + */ + pre_num = 10; + /* buf0/buf1/buf2/mtnp/mcvec */ + post_num = 6; + } + if (canvas_pool_alloc_canvas_table("di_pre", + &di_pre_idx[0][0], pre_num, CANVAS_MAP_TYPE_1)) { + pr_dbg("%s allocate di pre canvas error.\n", __func__); + return 1; + } + if (di_pre_rdma_enable) { + if (canvas_pool_alloc_canvas_table("di_pre", + &di_pre_idx[1][0], pre_num, CANVAS_MAP_TYPE_1)) { + pr_dbg("%s allocate di pre canvas error.\n", __func__); + return 1; + } + } else { + pr_info("DI: pre canvas:"); + for (i = 0; i < pre_num; i++) { + di_pre_idx[1][i] = di_pre_idx[0][i]; + pr_info("\t[%d]\t[%d]\n", di_pre_idx[0][i], + di_pre_idx[1][i]); + } + pr_info("\n"); + } + if (canvas_pool_alloc_canvas_table("di_post", + &di_post_idx[0][0], post_num, CANVAS_MAP_TYPE_1)) { + pr_dbg("%s allocate di post canvas error.\n", __func__); + return 1; + } + +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + if (canvas_pool_alloc_canvas_table("di_post", + &di_post_idx[1][0], post_num, CANVAS_MAP_TYPE_1)) { + pr_dbg("%s allocate di post canvas error.\n", __func__); + return 1; + } +#else + for (i = 0; i < post_num; i++) { + di_post_idx[1][i] = di_post_idx[0][i]; + pr_info("\t[%d]\t[%d]\n", di_post_idx[0][i], di_post_idx[1][i]); + } +#endif + pr_info("DI: post canvas:"); + for (i = 0; i < post_num; i++) + pr_info("\t [%d] [%d]", di_post_idx[0][i], di_post_idx[1][i]); + pr_info("\n"); + return 0; +} +static void config_canvas_idx(struct di_buf_s *di_buf, int nr_canvas_idx, + int mtn_canvas_idx) +{ + unsigned int height = 0; + + if (!di_buf) + return; + if (di_buf->canvas_config_flag == 1) { + if (nr_canvas_idx >= 0) { + /* linked two interlace buffer should double height*/ + if (di_buf->di_wr_linked_buf) + height = (di_buf->canvas_height << 1); + else + height = di_buf->canvas_height; + di_buf->nr_canvas_idx = nr_canvas_idx; + canvas_config(nr_canvas_idx, di_buf->nr_adr, + di_buf->canvas_width[NR_CANVAS], height, 0, 0); + } + } else if (di_buf->canvas_config_flag == 2) { + if (nr_canvas_idx >= 0) { + di_buf->nr_canvas_idx = nr_canvas_idx; + canvas_config(nr_canvas_idx, di_buf->nr_adr, + di_buf->canvas_width[NR_CANVAS], + di_buf->canvas_height, 0, 0); + } + if (mtn_canvas_idx >= 0) { + di_buf->mtn_canvas_idx = mtn_canvas_idx; + canvas_config(mtn_canvas_idx, di_buf->mtn_adr, + di_buf->canvas_width[MTN_CANVAS], + di_buf->canvas_height, 0, 0); + } + } + if (nr_canvas_idx >= 0) { + di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; + di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; + } +} + +#ifdef NEW_DI_V1 +static void config_cnt_canvas_idx(struct di_buf_s *di_buf, + unsigned int cnt_canvas_idx) +{ + + if (!di_buf) + return; + + di_buf->cnt_canvas_idx = cnt_canvas_idx; + canvas_config( + cnt_canvas_idx, di_buf->cnt_adr, + di_buf->canvas_width[MTN_CANVAS], + di_buf->canvas_height, 0, 0); +} +#endif + +static void config_mcinfo_canvas_idx(struct di_buf_s *di_buf, + int mcinfo_canvas_idx) +{ + + if (!di_buf) + return; + + di_buf->mcinfo_canvas_idx = mcinfo_canvas_idx; + canvas_config( + mcinfo_canvas_idx, di_buf->mcinfo_adr, + di_buf->canvas_height, 2, 0, 0); +} +static void config_mcvec_canvas_idx(struct di_buf_s *di_buf, + int mcvec_canvas_idx) +{ + + if (!di_buf) + return; + + di_buf->mcvec_canvas_idx = mcvec_canvas_idx; + canvas_config( + mcvec_canvas_idx, di_buf->mcvec_adr, + di_buf->canvas_width[MV_CANVAS], + di_buf->canvas_height, 0, 0); +} + + +#else + +static void config_canvas(struct di_buf_s *di_buf) +{ + unsigned int height = 0; + + if (!di_buf) + return; + + if (di_buf->canvas_config_flag == 1) { + /* linked two interlace buffer should double height*/ + if (di_buf->di_wr_linked_buf) + height = (di_buf->canvas_height << 1); + else + height = di_buf->canvas_height; + canvas_config(di_buf->nr_canvas_idx, di_buf->nr_adr, + di_buf->canvas_width[NR_CANVAS], height, 0, 0); + di_buf->canvas_config_flag = 0; + } else if (di_buf->canvas_config_flag == 2) { + canvas_config(di_buf->nr_canvas_idx, di_buf->nr_adr, + di_buf->canvas_width[MV_CANVAS], + di_buf->canvas_height, 0, 0); + canvas_config(di_buf->mtn_canvas_idx, di_buf->mtn_adr, + di_buf->canvas_width[MTN_CANVAS], + di_buf->canvas_height, 0, 0); + di_buf->canvas_config_flag = 0; + } +} + +#endif +#ifdef CONFIG_CMA +void di_cma_alloc(void) +{ + unsigned int i, start_time, end_time, delta_time; + + if (bypass_4K == 1) { + pr_dbg("%s:di don't need alloc mem for 4k input\n", __func__); + return; + } + start_time = jiffies_to_msecs(jiffies); + for (i = 0; (i < local_buf_num); i++) { + struct di_buf_s *di_buf = &(di_buf_local[i]); + + int ii = USED_LOCAL_BUF_MAX; + + if ((used_post_buf_index != -1) && + (new_keep_last_frame_enable)) { + for (ii = 0; ii < USED_LOCAL_BUF_MAX; ii++) { + if (i == used_local_buf_index[ii]) { + pr_dbg("%s skip %d,cma_alloc=%d\n", + __func__, i, + de_devp->cma_alloc[i]); + break; + } + } + } + if ((ii >= USED_LOCAL_BUF_MAX) && + (de_devp->cma_alloc[i] == 0)) { + de_devp->pages[i] = + dma_alloc_from_contiguous(&(de_devp->pdev->dev), + de_devp->buffer_size >> PAGE_SHIFT, 0); + if (de_devp->pages[i]) { + de_devp->mem_start = + page_to_phys(de_devp->pages[i]); + de_devp->cma_alloc[i] = 1; + pr_dbg("DI CMA allocate addr:0x%x[%d] ok.\n", + (unsigned int)de_devp->mem_start, i); + } else { + pr_dbg("DI CMA allocate %d fail.\n", i); + } + if (di_pre_stru.buf_alloc_mode) { + di_buf->nr_adr = de_devp->mem_start; + } else { + di_buf->nr_adr = de_devp->mem_start; + di_buf->mtn_adr = de_devp->mem_start + + di_pre_stru.nr_size; +#ifdef NEW_DI_V1 + di_buf->cnt_adr = de_devp->mem_start + + di_pre_stru.nr_size + + di_pre_stru.mtn_size; +#endif + if (mcpre_en) { + di_buf->mcvec_adr = de_devp->mem_start + + di_pre_stru.nr_size + + di_pre_stru.mtn_size + + di_pre_stru.count_size; + di_buf->mcinfo_adr = + de_devp->mem_start + + di_pre_stru.nr_size + + di_pre_stru.mtn_size + + di_pre_stru.count_size + + di_pre_stru.mv_size; + } + } + } + } + end_time = jiffies_to_msecs(jiffies); + delta_time = end_time - start_time; + pr_dbg("%s:alloc use %d ms(%d~%d)\n", __func__, delta_time, + start_time, end_time); +} +void di_cma_release(void) +{ + unsigned int i, start_time, end_time, delta_time; + + start_time = jiffies_to_msecs(jiffies); + for (i = 0; (i < local_buf_num); i++) { + int ii = USED_LOCAL_BUF_MAX; + + if ((used_post_buf_index != -1) && + (new_keep_last_frame_enable)) { + for (ii = 0; ii < USED_LOCAL_BUF_MAX; ii++) { + if (i == used_local_buf_index[ii]) { + pr_dbg("%s skip %d,cma_alloc=%d\n", + __func__, i, + de_devp->cma_alloc[i]); + break; + } + } + } + if ((ii >= USED_LOCAL_BUF_MAX) && + (de_devp->cma_alloc[i] == 1)) { + if (dma_release_from_contiguous(&(de_devp->pdev->dev), + de_devp->pages[i], + de_devp->buffer_size >> PAGE_SHIFT)) { + de_devp->cma_alloc[i] = 0; + pr_dbg("DI CMA release %d ok.\n", i); + } else { + pr_dbg("DI CMA release %d fail.\n", i); + } + } + } + end_time = jiffies_to_msecs(jiffies); + delta_time = end_time - start_time; + pr_dbg("%s:release use %d ms(%d~%d)\n", __func__, delta_time, + start_time, end_time); +} +#endif +static int di_init_buf(int width, int height, unsigned char prog_flag) +{ + int i; + int canvas_height = height + 8; + + unsigned int di_buf_size = 0, di_post_buf_size = 0, mtn_size = 0; + unsigned int nr_size = 0, count_size = 0, mv_size = 0, mc_size = 0; + unsigned int nr_width = width, mtn_width = width, mv_width = width; + unsigned long di_post_mem = 0; + + frame_count = 0; + disp_frame_count = 0; + cur_post_ready_di_buf = NULL; + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + if (vframe_in[i]) { + vf_put(vframe_in[i], VFM_NAME); + vf_notify_provider( + VFM_NAME, VFRAME_EVENT_RECEIVER_PUT, NULL); + vframe_in[i] = NULL; + } + } + memset(&di_pre_stru, 0, sizeof(di_pre_stru)); + if (nr10bit_surpport) { + if (full_422_pack) + nr_width = (width * 5) / 4;/* 2400 roundup to 2432*/ + else + nr_width = (width * 3) / 2;/* 2880 roundup to 2944*/ + } else { + nr_width = width; + } + /* make sure canvas width must be divided by 256 */ + if ((nr_width<<1)%256) + nr_width = roundup(nr_width, (256>>1)); + + if ((mtn_width>>1)%256) + mtn_width = roundup(mtn_width, (256<<1)); /* roundup to 2048*/ + + if (((mv_width<<1)/5)%256) + mv_width = roundup(mv_width, ((256*5)>>1)); + + if (prog_flag) { + di_pre_stru.prog_proc_type = 1; + di_pre_stru.buf_alloc_mode = 1; + di_buf_size = nr_width * canvas_height * 2; + di_buf_size = roundup(di_buf_size, PAGE_SIZE); + local_buf_num = de_devp->mem_size / di_buf_size; + if (local_buf_num > (2 * MAX_LOCAL_BUF_NUM)) + local_buf_num = 2 * MAX_LOCAL_BUF_NUM; + + if (local_buf_num >= 6) + new_keep_last_frame_enable = 1; + else + new_keep_last_frame_enable = 0; + } else { + di_pre_stru.prog_proc_type = 0; + di_pre_stru.buf_alloc_mode = 0; + /*nr_size(bits)=w*active_h*8*2(yuv422) + * mtn(bits)=w*active_h*4 + * cont(bits)=w*active_h*4 mv(bits)=w*active_h/5*16 + * mcinfo(bits)=active_h*16 + */ + nr_size = (nr_width * canvas_height)*8*2/16; + mtn_size = (mtn_width * canvas_height)*4/16; + count_size = (mtn_width * canvas_height)*4/16; + mv_size = (mv_width * canvas_height)/5; + mc_size = canvas_height; + if (mcpre_en) { + di_buf_size = nr_size + mtn_size + count_size + + mv_size + mc_size; + } else { +#ifdef NEW_DI_V1 + di_buf_size = nr_size + mtn_size + count_size; +#else + di_buf_size = nr_size + mtn_size; +#endif + } + di_buf_size = roundup(di_buf_size, PAGE_SIZE); + local_buf_num = de_devp->mem_size / di_buf_size; + + if (post_wr_en && post_wr_surpport) { + local_buf_num = (de_devp->mem_size + + (nr_width*canvas_height<<2)) / + (di_buf_size + (nr_width*canvas_height<<1)); + } + + if (local_buf_num > MAX_LOCAL_BUF_NUM) + local_buf_num = MAX_LOCAL_BUF_NUM; + + if (local_buf_num >= 8) + new_keep_last_frame_enable = 1; + else + new_keep_last_frame_enable = 0; + } + de_devp->buffer_size = di_buf_size; + di_pre_stru.nr_size = nr_size; + di_pre_stru.count_size = count_size; + di_pre_stru.mtn_size = mtn_size; + di_pre_stru.mv_size = mv_size; + di_pre_stru.mcinfo_size = mc_size; + same_w_r_canvas_count = 0; + same_field_top_count = 0; + same_field_bot_count = 0; + + queue_init(local_buf_num); + for (i = 0; i < local_buf_num; i++) { + struct di_buf_s *di_buf = &(di_buf_local[i]); + int ii = USED_LOCAL_BUF_MAX; + + if ((used_post_buf_index != -1) && + (new_keep_last_frame_enable)) { + for (ii = 0; ii < USED_LOCAL_BUF_MAX; ii++) { + if (i == used_local_buf_index[ii]) { + di_print("%s skip %d\n", __func__, i); + break; + } + } + } + + if (ii >= USED_LOCAL_BUF_MAX) { + memset(di_buf, 0, sizeof(struct di_buf_s)); + di_buf->type = VFRAME_TYPE_LOCAL; + di_buf->pre_ref_count = 0; + di_buf->post_ref_count = 0; + di_buf->canvas_width[NR_CANVAS] = (nr_width<<1); + di_buf->canvas_width[MTN_CANVAS] = (mtn_width>>1); + di_buf->canvas_width[MV_CANVAS] = (mv_width<<1)/5; + if (prog_flag) { + di_buf->canvas_height = canvas_height; + di_buf->nr_adr = de_devp->mem_start + + di_buf_size * i; + di_buf->canvas_config_flag = 1; + } else { + di_buf->canvas_height = (canvas_height>>1); + di_buf->nr_adr = de_devp->mem_start + + di_buf_size * i; + di_buf->mtn_adr = de_devp->mem_start + + di_buf_size * i + + nr_size; +#ifdef NEW_DI_V1 + di_buf->cnt_adr = de_devp->mem_start + + di_buf_size * i + + nr_size + mtn_size; +#endif + + if (mcpre_en) { + di_buf->mcvec_adr = de_devp->mem_start + + di_buf_size * i + + nr_size + mtn_size + count_size; + di_buf->mcinfo_adr = + de_devp->mem_start + + di_buf_size * i + nr_size + + mtn_size + count_size + mv_size; + } + di_buf->canvas_config_flag = 2; + } + di_buf->index = i; + di_buf->vframe = &(vframe_local[i]); + di_buf->vframe->private_data = di_buf; + di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; + di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; + di_buf->queue_index = -1; + di_buf->invert_top_bot_flag = 0; + queue_in(di_buf, QUEUE_LOCAL_FREE); + } + } +#ifdef CONFIG_CMA + if (de_devp->flag_cma == 1) { + pr_dbg("%s:cma alloc req time: %d ms\n", + __func__, jiffies_to_msecs(jiffies)); + di_pre_stru.cma_alloc_req = 1; + up(&di_sema); + } +#endif + if (post_wr_en && post_wr_surpport) { + di_post_mem = de_devp->mem_start + di_buf_size*local_buf_num; + di_post_buf_size = width * canvas_height*2; + /* pre buffer must 2 more than post buffer */ + di_post_stru.di_post_num = local_buf_num - 2; + pr_info("DI: di post buffer size %u byte.\n", di_post_buf_size); + } else { + di_post_stru.di_post_num = MAX_POST_BUF_NUM; + di_post_buf_size = 0; + } + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + struct di_buf_s *di_buf = &(di_buf_in[i]); + + if (di_buf) { + memset(di_buf, 0, sizeof(struct di_buf_s)); + di_buf->type = VFRAME_TYPE_IN; + di_buf->pre_ref_count = 0; + di_buf->post_ref_count = 0; + di_buf->vframe = &(vframe_in_dup[i]); + di_buf->vframe->private_data = di_buf; + di_buf->index = i; + di_buf->queue_index = -1; + di_buf->invert_top_bot_flag = 0; + queue_in(di_buf, QUEUE_IN_FREE); + } + } + + for (i = 0; i < di_post_stru.di_post_num; i++) { + struct di_buf_s *di_buf = &(di_buf_post[i]); + + if (di_buf) { + if (i != used_post_buf_index) { + memset(di_buf, 0, sizeof(struct di_buf_s)); + di_buf->type = VFRAME_TYPE_POST; + di_buf->index = i; + di_buf->vframe = &(vframe_post[i]); + di_buf->vframe->private_data = di_buf; + di_buf->queue_index = -1; + di_buf->invert_top_bot_flag = 0; + if (post_wr_en && post_wr_surpport) { + di_buf->canvas_width[NR_CANVAS] = + (nr_width << 1); + di_buf->canvas_height = canvas_height; + di_buf->canvas_config_flag = 1; + di_buf->nr_adr = di_post_mem + + di_post_buf_size*i; + } + queue_in(di_buf, QUEUE_POST_FREE); + } + } + } + return 0; +} + +static void di_uninit_buf(void) +{ + struct di_buf_s *p = NULL;/* , *ptmp; */ + int i, ii = 0; + int itmp; + + /* vframe_t* cur_vf = get_cur_dispbuf(); */ + if (!queue_empty(QUEUE_DISPLAY)) { + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) + used_local_buf_index[i] = -1; + + used_post_buf_index = -1; + } + + queue_for_each_entry(p, ptmp, QUEUE_DISPLAY, list) { + if (p->di_buf[0]->type != VFRAME_TYPE_IN && + (p->process_fun_index != PROCESS_FUN_NULL) && + (ii < USED_LOCAL_BUF_MAX) && + (p->index == di_post_stru.cur_disp_index)) { + used_post_buf_index = p->index; + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) { + if (p->di_buf_dup_p[i] == NULL) + continue; + used_local_buf_index[ii] = + p->di_buf_dup_p[i]->index; + /* prepare for recycle + * the keep buffer + */ + p->di_buf_dup_p[i]->pre_ref_count = 0; + p->di_buf_dup_p[i]->post_ref_count = 0; + if ((p->di_buf_dup_p[i]->queue_index >= 0) && + (p->di_buf_dup_p[i]->queue_index < QUEUE_NUM)) { + if (is_in_queue(p->di_buf_dup_p[i], + p->di_buf_dup_p[i]->queue_index)) + queue_out(p->di_buf_dup_p[i]); + } + ii++; + if (p->di_buf_dup_p[i]->di_wr_linked_buf) + used_local_buf_index[ii] = + p->di_buf_dup_p[i]->di_wr_linked_buf->index; + } + queue_out(p); + break; + } + } + if (used_post_buf_index != -1) { + pr_info("%s keep cur di_buf %d (%d %d %d)\n", + __func__, used_post_buf_index, used_local_buf_index[0], + used_local_buf_index[1], used_local_buf_index[2]); + } + queue_init(0); + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + if (vframe_in[i]) { + vf_put(vframe_in[i], VFM_NAME); + vf_notify_provider( + VFM_NAME, VFRAME_EVENT_RECEIVER_PUT, NULL); + vframe_in[i] = NULL; + } + } +#ifdef CONFIG_CMA + if (de_devp->flag_cma == 1) { + pr_dbg("%s:cma release req time: %d ms\n", + __func__, jiffies_to_msecs(jiffies)); + di_pre_stru.cma_release_req = 1; + up(&di_sema); + } +#endif + di_pre_stru.pre_de_process_done = 0; + di_pre_stru.pre_de_busy = 0; + if (post_wr_en && post_wr_surpport) { + di_post_stru.cur_post_buf = NULL; + di_post_stru.post_de_busy = 0; + di_post_stru.de_post_process_done = 0; + } +} + +static void log_buffer_state(unsigned char *tag) +{ + if (di_log_flag & DI_LOG_BUFFER_STATE) { + struct di_buf_s *p = NULL;/* , *ptmp; */ + int itmp; + int in_free = 0; + int local_free = 0; + int pre_ready = 0; + int post_free = 0; + int post_ready = 0; + int post_ready_ext = 0; + int display = 0; + int display_ext = 0; + int recycle = 0; + int di_inp = 0; + int di_wr = 0; + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + + di_lock_irqfiq_save(irq_flag2, fiq_flag); + in_free = list_count(QUEUE_IN_FREE); + local_free = list_count(QUEUE_LOCAL_FREE); + pre_ready = list_count(QUEUE_PRE_READY); + post_free = list_count(QUEUE_POST_FREE); + post_ready = list_count(QUEUE_POST_READY); + queue_for_each_entry(p, ptmp, QUEUE_POST_READY, list) { + if (p->di_buf[0]) + post_ready_ext++; + + if (p->di_buf[1]) + post_ready_ext++; + } + queue_for_each_entry(p, ptmp, QUEUE_DISPLAY, list) { + display++; + if (p->di_buf[0]) + display_ext++; + + if (p->di_buf[1]) + display_ext++; + } + recycle = list_count(QUEUE_RECYCLE); + + if (di_pre_stru.di_inp_buf) + di_inp++; + if (di_pre_stru.di_wr_buf) + di_wr++; + + if (buf_state_log_threshold == 0) + buf_state_log_start = 0; + else if (post_ready < buf_state_log_threshold) + buf_state_log_start = 1; + + if (buf_state_log_start) { + di_print( + "[%s]i %d, i_f %d/%d, l_f %d/%d, pre_r %d, post_f %d/%d,", + tag, + provider_vframe_level, + in_free, MAX_IN_BUF_NUM, + local_free, local_buf_num, + pre_ready, + post_free, MAX_POST_BUF_NUM); + di_print( + "post_r (%d:%d), disp (%d:%d),rec %d, di_i %d, di_w %d\n", + post_ready, post_ready_ext, + display, display_ext, + recycle, + di_inp, di_wr + ); + } + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + } +} + + +static void dump_state(void) +{ + struct di_buf_s *p = NULL;/* , *ptmp; */ + int itmp; + int i; + + dump_state_flag = 1; + pr_info("version %s, provider vframe level %d,", + version_s, provider_vframe_level); + pr_info("init_flag %d, is_bypass %d, receiver_is_amvideo %d\n", + init_flag, is_bypass(NULL), receiver_is_amvideo); + pr_info("recovery_flag = %d, recovery_log_reason=%d, di_blocking=%d", + recovery_flag, recovery_log_reason, di_blocking); + pr_info("recovery_log_queue_idx=%d, recovery_log_di_buf=0x%p\n", + recovery_log_queue_idx, recovery_log_di_buf); + pr_info("buffer_size=%d,mem_flag=%d\n", de_devp->buffer_size, mem_flag); + pr_info("new_keep_last_frame_enable %d,", new_keep_last_frame_enable); + pr_info("used_post_buf_index %d(0x%p),", used_post_buf_index, + (used_post_buf_index == + -1) ? NULL : &(di_buf_post[used_post_buf_index])); + pr_info("used_local_buf_index:\n"); + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) { + int tmp = used_local_buf_index[i]; + + pr_info("%d(0x%p) ", tmp, + (tmp == -1) ? NULL : &(di_buf_local[tmp])); + } + + pr_info("\nin_free_list (max %d):\n", MAX_IN_BUF_NUM); + queue_for_each_entry(p, ptmp, QUEUE_IN_FREE, list) { + pr_info("index %2d, 0x%p, type %d\n", + p->index, p, p->type); + } + pr_info("local_free_list (max %d):\n", local_buf_num); + queue_for_each_entry(p, ptmp, QUEUE_LOCAL_FREE, list) { + pr_info("index %2d, 0x%p, type %d\n", p->index, p, p->type); + } + + pr_info("post_doing_list:\n"); + queue_for_each_entry(p, ptmp, QUEUE_POST_DOING, list) { + print_di_buf(p, 2); + } + pr_info("pre_ready_list:\n"); + queue_for_each_entry(p, ptmp, QUEUE_PRE_READY, list) { + print_di_buf(p, 2); + } + pr_info("post_free_list (max %d):\n", di_post_stru.di_post_num); + queue_for_each_entry(p, ptmp, QUEUE_POST_FREE, list) { + pr_info("index %2d, 0x%p, type %d, vframetype 0x%x\n", + p->index, p, p->type, p->vframe->type); + } + pr_info("post_ready_list:\n"); + queue_for_each_entry(p, ptmp, QUEUE_POST_READY, list) { + print_di_buf(p, 2); + print_di_buf(p->di_buf[0], 1); + print_di_buf(p->di_buf[1], 1); + } + pr_info("display_list:\n"); + queue_for_each_entry(p, ptmp, QUEUE_DISPLAY, list) { + print_di_buf(p, 2); + print_di_buf(p->di_buf[0], 1); + print_di_buf(p->di_buf[1], 1); + } + pr_info("recycle_list:\n"); + queue_for_each_entry(p, ptmp, QUEUE_RECYCLE, list) { + pr_info( +"index %d, 0x%p, type %d, vframetype 0x%x pre_ref_count %d post_ref_count %d\n", + p->index, p, p->type, + p->vframe->type, + p->pre_ref_count, + p->post_ref_count); + if (p->di_wr_linked_buf) { + pr_info( + "linked index %2d, 0x%p, type %d pre_ref_count %d post_ref_count %d\n", + p->di_wr_linked_buf->index, + p->di_wr_linked_buf, + p->di_wr_linked_buf->type, + p->di_wr_linked_buf->pre_ref_count, + p->di_wr_linked_buf->post_ref_count); + } + } + if (di_pre_stru.di_inp_buf) { + pr_info("di_inp_buf:index %d, 0x%p, type %d\n", + di_pre_stru.di_inp_buf->index, + di_pre_stru.di_inp_buf, + di_pre_stru.di_inp_buf->type); + } else { + pr_info("di_inp_buf: NULL\n"); + } + if (di_pre_stru.di_wr_buf) { + pr_info("di_wr_buf:index %d, 0x%p, type %d\n", + di_pre_stru.di_wr_buf->index, + di_pre_stru.di_wr_buf, + di_pre_stru.di_wr_buf->type); + } else { + pr_info("di_wr_buf: NULL\n"); + } + dump_di_pre_stru(&di_pre_stru); + dump_di_post_stru(&di_post_stru); + pr_info("vframe_in[]:"); + + for (i = 0; i < MAX_IN_BUF_NUM; i++) + pr_info("0x%p ", vframe_in[i]); + + pr_info("\n"); + pr_info("vf_peek()=>0x%p,di_process_cnt = %d\n", + vf_peek(VFM_NAME), di_process_cnt); + pr_info("video_peek_cnt = %d,force_trig_cnt = %d\n", + video_peek_cnt, force_trig_cnt); + dump_state_flag = 0; +} + +static unsigned char check_di_buf(struct di_buf_s *di_buf, int reason) +{ + int error = 0; + + if (di_buf == NULL) { + pr_dbg("%s: Error %d, di_buf is NULL\n", __func__, reason); + return 1; + } + + if (di_buf->type == VFRAME_TYPE_IN) { + if (di_buf->vframe != &vframe_in_dup[di_buf->index]) + error = 1; + } else if (di_buf->type == VFRAME_TYPE_LOCAL) { + if (di_buf->vframe != + &vframe_local[di_buf->index]) + error = 1; + } else if (di_buf->type == VFRAME_TYPE_POST) { + if (di_buf->vframe != &vframe_post[di_buf->index]) + error = 1; + } else { + error = 1; + } + + if (error) { + pr_dbg( + "%s: Error %d, di_buf wrong\n", __func__, + reason); + if (recovery_flag == 0) + recovery_log_reason = reason; + recovery_flag++; + dump_di_buf(di_buf); + return 1; + } + + return 0; +} +/* + * di pre process + */ +static void +config_di_mcinford_mif(struct DI_MC_MIF_s *di_mcinford_mif, + struct di_buf_s *di_buf) +{ + if (di_buf) { + di_mcinford_mif->size_x = di_buf->vframe->height / 4 - 1; + di_mcinford_mif->size_y = 1; + di_mcinford_mif->canvas_num = di_buf->mcinfo_canvas_idx; + } +} +static void +config_di_pre_mc_mif(struct DI_MC_MIF_s *di_mcinfo_mif, + struct DI_MC_MIF_s *di_mcvec_mif, + struct di_buf_s *di_buf) +{ + if (di_buf) { + di_mcinfo_mif->size_x = di_buf->vframe->height / 4 - 1; + di_mcinfo_mif->size_y = 1; + di_mcinfo_mif->canvas_num = di_buf->mcinfo_canvas_idx; + + di_mcvec_mif->size_x = (di_buf->vframe->width + 4) / 5 - 1; + di_mcvec_mif->size_y = di_buf->vframe->height / 2 - 1; + di_mcvec_mif->canvas_num = di_buf->mcvec_canvas_idx; + } +} +#ifdef NEW_DI_V1 +static void config_di_cnt_mif(struct DI_SIM_MIF_s *di_cnt_mif, + struct di_buf_s *di_buf) +{ + if (di_buf) { + di_cnt_mif->start_x = 0; + di_cnt_mif->end_x = di_buf->vframe->width - 1; + di_cnt_mif->start_y = 0; + di_cnt_mif->end_y = di_buf->vframe->height / 2 - 1; + di_cnt_mif->canvas_num = di_buf->cnt_canvas_idx; + } +} +#endif + +static void +config_di_wr_mif(struct DI_SIM_MIF_s *di_nrwr_mif, + struct DI_SIM_MIF_s *di_mtnwr_mif, + struct di_buf_s *di_buf, + vframe_t *in_vframe) +{ + di_nrwr_mif->canvas_num = di_buf->nr_canvas_idx; + di_nrwr_mif->start_x = 0; + di_nrwr_mif->end_x = in_vframe->width - 1; + di_nrwr_mif->start_y = 0; + if (di_buf->vframe->bitdepth & BITDEPTH_Y10) + di_nrwr_mif->bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:1; + else + di_nrwr_mif->bit_mode = 0; + if (di_pre_stru.prog_proc_type == 0) + di_nrwr_mif->end_y = in_vframe->height / 2 - 1; + else + di_nrwr_mif->end_y = in_vframe->height - 1; + if (di_pre_stru.prog_proc_type == 0) { + di_mtnwr_mif->start_x = 0; + di_mtnwr_mif->end_x = in_vframe->width - 1; + di_mtnwr_mif->start_y = 0; + di_mtnwr_mif->end_y = in_vframe->height / 2 - 1; + di_mtnwr_mif->canvas_num = di_buf->mtn_canvas_idx; + } +} + +static void config_di_mif(struct DI_MIF_s *di_mif, struct di_buf_s *di_buf) +{ + if (di_buf == NULL) + return; + di_mif->canvas0_addr0 = + di_buf->vframe->canvas0Addr & 0xff; + di_mif->canvas0_addr1 = + (di_buf->vframe->canvas0Addr >> 8) & 0xff; + di_mif->canvas0_addr2 = + (di_buf->vframe->canvas0Addr >> 16) & 0xff; + + if (di_buf->vframe->bitdepth & BITDEPTH_Y10) { + if (di_buf->vframe->type & VIDTYPE_VIU_444) + di_mif->bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:2; + else if (di_buf->vframe->type & VIDTYPE_VIU_422) + di_mif->bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:1; + } else { + di_mif->bit_mode = 0; + } + if (di_buf->vframe->type & VIDTYPE_VIU_422) { + /* from vdin or local vframe */ + if ((!is_progressive(di_buf->vframe)) + || (di_pre_stru.prog_proc_type) + ) { + di_mif->video_mode = 0; + di_mif->set_separate_en = 0; + di_mif->src_field_mode = 0; + di_mif->output_field_num = 0; + di_mif->luma_x_start0 = 0; + di_mif->luma_x_end0 = + di_buf->vframe->width - 1; + di_mif->luma_y_start0 = 0; + if (di_pre_stru.prog_proc_type) + di_mif->luma_y_end0 = + di_buf->vframe->height - 1; + else + di_mif->luma_y_end0 = + di_buf->vframe->height / 2 - 1; + di_mif->chroma_x_start0 = 0; + di_mif->chroma_x_end0 = 0; + di_mif->chroma_y_start0 = 0; + di_mif->chroma_y_end0 = 0; + di_mif->canvas0_addr0 = + di_buf->vframe->canvas0Addr & 0xff; + di_mif->canvas0_addr1 = + (di_buf->vframe->canvas0Addr >> 8) & 0xff; + di_mif->canvas0_addr2 = + (di_buf->vframe->canvas0Addr >> 16) & 0xff; + } + } else { + if (di_buf->vframe->type & VIDTYPE_VIU_444) + di_mif->video_mode = 1; + else + di_mif->video_mode = 0; + if (di_buf->vframe->type & VIDTYPE_VIU_NV21) + di_mif->set_separate_en = 2; + else + di_mif->set_separate_en = 1; + + + if (is_progressive(di_buf->vframe) && + (di_pre_stru.prog_proc_type)) { + di_mif->src_field_mode = 0; + di_mif->output_field_num = 0; /* top */ + di_mif->luma_x_start0 = 0; + di_mif->luma_x_end0 = + di_buf->vframe->width - 1; + di_mif->luma_y_start0 = 0; + di_mif->luma_y_end0 = + di_buf->vframe->height - 1; + di_mif->chroma_x_start0 = 0; + di_mif->chroma_x_end0 = + di_buf->vframe->width / 2 - 1; + di_mif->chroma_y_start0 = 0; + di_mif->chroma_y_end0 = + di_buf->vframe->height / 2 - 1; + } else { + di_mif->src_prog = di_pre_stru.cur_prog_flag; + di_mif->src_field_mode = 1; + if ( + (di_buf->vframe->type & VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_TOP) { + di_mif->output_field_num = 0; /* top */ + di_mif->luma_x_start0 = 0; + di_mif->luma_x_end0 = + di_buf->vframe->width - 1; + di_mif->luma_y_start0 = 0; + di_mif->luma_y_end0 = + di_buf->vframe->height - 2; + di_mif->chroma_x_start0 = 0; + di_mif->chroma_x_end0 = + di_buf->vframe->width / 2 - 1; + di_mif->chroma_y_start0 = 0; + di_mif->chroma_y_end0 = + di_buf->vframe->height / 2 + - (di_mif->src_prog?1:2); + } else { + di_mif->output_field_num = 1; + /* bottom */ + di_mif->luma_x_start0 = 0; + di_mif->luma_x_end0 = + di_buf->vframe->width - 1; + di_mif->luma_y_start0 = 1; + di_mif->luma_y_end0 = + di_buf->vframe->height - 1; + di_mif->chroma_x_start0 = 0; + di_mif->chroma_x_end0 = + di_buf->vframe->width / 2 - 1; + di_mif->chroma_y_start0 = + (di_mif->src_prog?0:1); + di_mif->chroma_y_end0 = + di_buf->vframe->height / 2 - 1; + } + } + } +} + +static void pre_de_process(void) +{ + int chan2_field_num = 1; + int canvases_idex = di_pre_stru.field_count_for_cont % 2; + +#ifdef NEW_DI_V1 + int cont_rd = 1; +#endif + unsigned int blkhsize = 0; + unsigned int di_mtn_1_ctrl1 = RDMA_RD(DI_MTN_1_CTRL1); + + di_print("%s: start\n", __func__); + di_pre_stru.pre_de_busy = 1; + di_pre_stru.pre_de_busy_timer_count = 0; + + config_di_mif(&di_pre_stru.di_inp_mif, di_pre_stru.di_inp_buf); + /* pr_dbg("set_separate_en=%d vframe->type %d\n", + * di_pre_stru.di_inp_mif.set_separate_en, + * di_pre_stru.di_inp_buf->vframe->type); + */ +#ifdef DI_USE_FIXED_CANVAS_IDX + if ((di_pre_stru.di_mem_buf_dup_p != NULL && + di_pre_stru.di_mem_buf_dup_p != di_pre_stru.di_inp_buf)) { + config_canvas_idx(di_pre_stru.di_mem_buf_dup_p, + di_pre_idx[canvases_idex][0], -1); +#ifdef NEW_DI_V1 + config_cnt_canvas_idx(di_pre_stru.di_mem_buf_dup_p, + di_pre_idx[canvases_idex][1]); +#endif + } + if (di_pre_stru.di_chan2_buf_dup_p != NULL) { + config_canvas_idx(di_pre_stru.di_chan2_buf_dup_p, + di_pre_idx[canvases_idex][2], -1); +#ifdef NEW_DI_V1 + config_cnt_canvas_idx(di_pre_stru.di_chan2_buf_dup_p, + di_pre_idx[canvases_idex][3]); +#endif + } + config_canvas_idx(di_pre_stru.di_wr_buf, + di_pre_idx[canvases_idex][4], di_pre_idx[canvases_idex][5]); +#ifdef NEW_DI_V1 + config_cnt_canvas_idx(di_pre_stru.di_wr_buf, + di_pre_idx[canvases_idex][6]); +#endif + if (mcpre_en) { + if (di_pre_stru.di_chan2_buf_dup_p != NULL) + config_mcinfo_canvas_idx(di_pre_stru.di_chan2_buf_dup_p, + di_pre_idx[canvases_idex][7]); + config_mcinfo_canvas_idx(di_pre_stru.di_wr_buf, + di_pre_idx[canvases_idex][8]); + config_mcvec_canvas_idx(di_pre_stru.di_wr_buf, + di_pre_idx[canvases_idex][9]); + } +#endif + config_di_mif(&di_pre_stru.di_mem_mif, di_pre_stru.di_mem_buf_dup_p); + config_di_mif(&di_pre_stru.di_chan2_mif, + di_pre_stru.di_chan2_buf_dup_p); + config_di_wr_mif(&di_pre_stru.di_nrwr_mif, &di_pre_stru.di_mtnwr_mif, + di_pre_stru.di_wr_buf, di_pre_stru.di_inp_buf->vframe); + +#ifdef NEW_DI_V1 + config_di_cnt_mif(&di_pre_stru.di_contp2rd_mif, + di_pre_stru.di_mem_buf_dup_p); + config_di_cnt_mif(&di_pre_stru.di_contprd_mif, + di_pre_stru.di_chan2_buf_dup_p); + config_di_cnt_mif(&di_pre_stru.di_contwr_mif, di_pre_stru.di_wr_buf); +#endif + if (mcpre_en) { + config_di_mcinford_mif(&di_pre_stru.di_mcinford_mif, + di_pre_stru.di_chan2_buf_dup_p); + config_di_pre_mc_mif(&di_pre_stru.di_mcinfowr_mif, + &di_pre_stru.di_mcvecwr_mif, di_pre_stru.di_wr_buf); + } + + if ((di_pre_stru.di_chan2_buf_dup_p) && + ((di_pre_stru.di_chan2_buf_dup_p->vframe->type & VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP)) + chan2_field_num = 0; + + RDMA_WR(DI_PRE_SIZE, di_pre_stru.di_nrwr_mif.end_x | + (di_pre_stru.di_nrwr_mif.end_y << 16)); + if (mcpre_en) { + blkhsize = (di_pre_stru.di_nrwr_mif.end_x + 4) / 5; + RDMA_WR(MCDI_HV_SIZEIN, (di_pre_stru.di_nrwr_mif.end_y + 1) + | ((di_pre_stru.di_nrwr_mif.end_x + 1) << 16)); + RDMA_WR(MCDI_HV_BLKSIZEIN, (overturn ? 3 : 0) << 30 + | blkhsize << 16 + | (di_pre_stru.di_nrwr_mif.end_y + 1)); + RDMA_WR(MCDI_BLKTOTAL, + blkhsize * (di_pre_stru.di_nrwr_mif.end_y + 1)); + } + /* set interrupt mask for pre module. + * we need to only leave one mask open + * to prevent multiple entry for de_irq + */ + RDMA_WR(DI_INTR_CTRL, + /* mask nrwr interrupt. */ + ((di_pre_stru.enable_mtnwr ? 1 : 0) << 16) | + /* mtnwr interrupt. */ + ((di_pre_stru.enable_mtnwr ? 0 : 1) << 17) | + /* mask diwr intrpt. */ + (((post_wr_en && post_wr_surpport)?0:1) << 18) | + (1 << 19) | /* mask hist check interrupt. */ + (1 << 20) | /* mask cont interrupt. */ + (1 << 21) | /* mask medi interrupt. */ + (1 << 22) | /* mask vecwr interrupt. */ + (1 << 23) | /* mask infwr interrupt. */ + #ifdef DET3D + ((det3d_en ? 0 : 1) << 24) | /* mask det3d interrupt. */ + #else + (1 << 24) | /* mask det3d interrupt. */ + #endif + ((post_wr_en && post_wr_surpport)?0xb:0xf)); + /* clean all pending interrupt bits. */ + + enable_di_pre_aml(&di_pre_stru.di_inp_mif, /* di_inp */ + &di_pre_stru.di_mem_mif, /* di_mem */ + &di_pre_stru.di_chan2_mif, /* chan2 */ + &di_pre_stru.di_nrwr_mif, /* nrwrite */ + &di_pre_stru.di_mtnwr_mif, /* mtn write */ +#ifdef NEW_DI_V1 + &di_pre_stru.di_contp2rd_mif, + &di_pre_stru.di_contprd_mif, + &di_pre_stru.di_contwr_mif, +#endif + 1, /* nr enable */ + di_pre_stru.enable_mtnwr, /* mtn enable */ + di_pre_stru.enable_pulldown_check, +/* pd32 check_en */ + di_pre_stru.enable_pulldown_check, +/* pd22 check_en */ + 0, /* hist check_en */ + chan2_field_num, +/* field num for chan2. 1 bottom, 0 top. */ + di_pre_stru.vdin2nr, /* pre vdin link. */ + pre_hold_line, /* hold line. */ + pre_urgent + ); + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) + enable_afbc_input(di_pre_stru.di_inp_buf->vframe); + + if (mcpre_en) { + if (!di_pre_stru.cur_prog_flag && mcpre_en) + enable_mc_di_pre(&di_pre_stru.di_mcinford_mif, + &di_pre_stru.di_mcinfowr_mif, + &di_pre_stru.di_mcvecwr_mif, pre_urgent); + } + if (di_pre_stru.cur_prog_flag == 1 || di_pre_stru.enable_mtnwr == 0) { + di_mtn_1_ctrl1 &= (~(1 << 31)); /* disable contwr */ + di_mtn_1_ctrl1 &= (~(1 << 29)); /* disable txt */ + cont_rd = 0; + if (mcpre_en) + RDMA_WR(DI_ARB_CTRL, + (RDMA_RD(DI_ARB_CTRL) & (~0x303)) | 0xF0F); + else + RDMA_WR(DI_ARB_CTRL, + RDMA_RD(DI_ARB_CTRL) | 1 << 9 | 1 << 8 + | 1 << 1 | 1 << 0); + } else { + if (mcpre_en) + RDMA_WR(DI_ARB_CTRL, + RDMA_RD(DI_ARB_CTRL) | 1 << 9 | 1 << 8 + | 1 << 1 | 1 << 0 | 0xF0F); + else + RDMA_WR(DI_ARB_CTRL, + RDMA_RD(DI_ARB_CTRL) | 1 << 9 | 1 << 8 + | 1 << 1 | 1 << 0); + + di_mtn_1_ctrl1 |= (1 << 31); /* enable contwr */ + RDMA_WR(DI_PRE_CTRL, RDMA_RD(DI_PRE_CTRL) | (1 << 1)); + /* mtn must enable for mtn1 enable */ + di_mtn_1_ctrl1 &= (~(1 << 29));/* disable txt */ + cont_rd = 1; + } + if (di_pre_stru.field_count_for_cont >= 3) { + di_mtn_1_ctrl1 |= 1 << 29;/* enable txt */ + RDMA_WR(DI_PRE_CTRL, + RDMA_RD(DI_PRE_CTRL) | (cont_rd << 25)); +#ifdef NEW_DI_V4 + if ((!dnr_en) && (Rd(DNR_CTRL) != 0) && dnr_reg_update) + RDMA_WR(DNR_CTRL, 0); +#endif + if (mcpre_en) { + if ((di_pre_stru.cur_prog_flag == 0) && + (di_pre_stru.enable_mtnwr == 1) + ) + RDMA_WR(DI_MTN_CTRL1, + (mcpre_en ? 0x3000 : 0) | + RDMA_RD(DI_MTN_CTRL1)); + else + RDMA_WR(DI_MTN_CTRL1, + (0xffffcfff & RDMA_RD(DI_MTN_CTRL1))); + /* enable me(mc di) */ + if (di_pre_stru.field_count_for_cont == 4) { + di_mtn_1_ctrl1 &= (~(1 << 30)); + /* enable contp2rd and contprd */ + RDMA_WR(MCDI_MOTINEN, 1 << 1 | 1); + } + if (di_pre_stru.field_count_for_cont == 5) + RDMA_WR(MCDI_CTRL_MODE, 0x1bfff7ff); + /* disalbe reflinfo */ + } else { + di_mtn_1_ctrl1 &= (~(1 << 30)); + } + /* enable contp2rd and contprd */ + } else { + di_mtn_1_ctrl1 |= (1 << 30); + enable_film_mode_check( + di_pre_stru.di_inp_buf->vframe->width, + di_pre_stru.di_inp_buf->vframe->height / 2, + di_pre_stru.di_inp_buf->vframe->source_type); + if (mcpre_en) { + /* txtdet_en mode */ + RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 1, 1); + RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 9, 1); + RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 16, 1); + RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 28, 1); + RDMA_WR(MCDI_MOTINEN, 0); + RDMA_WR(DI_MTN_CTRL1, + (0xffffcfff & RDMA_RD(DI_MTN_CTRL1))); + /* disable me(mc di) */ + } +#ifdef NEW_DI_V4 + RDMA_WR(DNR_CTRL, 0); +#endif + } + di_pre_stru.field_count_for_cont++; + + RDMA_WR(DI_MTN_1_CTRL1, di_mtn_1_ctrl1); + di_apply_reg_cfg(0); +#ifdef SUPPORT_MPEG_TO_VDIN + if (mpeg2vdin_flag) { + struct vdin_arg_s vdin_arg; + struct vdin_v4l2_ops_s *vdin_ops = get_vdin_v4l2_ops(); + + vdin_arg.cmd = VDIN_CMD_FORCE_GO_FIELD; + if (vdin_ops->tvin_vdin_func) + vdin_ops->tvin_vdin_func(0, &vdin_arg); + } +#endif + + /* enable pre mif*/ + enable_di_pre_mif(1); + di_print("DI:buf[%d] irq start.\n", di_pre_stru.di_inp_buf->seq); +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA + if (di_pre_rdma_enable & 0x2) + rdma_config(de_devp->rdma_handle, RDMA_TRIGGER_MANUAL); + else if (di_pre_rdma_enable & 1) + rdma_config(de_devp->rdma_handle, RDMA_DEINT_IRQ); +#endif +} + +static void pre_de_done_buf_clear(void) +{ + struct di_buf_s *wr_buf = NULL; + + if (di_pre_stru.di_wr_buf) { + wr_buf = di_pre_stru.di_wr_buf; + if ((di_pre_stru.prog_proc_type == 2) && + wr_buf->di_wr_linked_buf) { + wr_buf->di_wr_linked_buf->pre_ref_count = 0; + wr_buf->di_wr_linked_buf->post_ref_count = 0; + queue_in(wr_buf->di_wr_linked_buf, QUEUE_RECYCLE); + wr_buf->di_wr_linked_buf = NULL; + } + wr_buf->pre_ref_count = 0; + wr_buf->post_ref_count = 0; + queue_in(wr_buf, QUEUE_RECYCLE); + di_pre_stru.di_wr_buf = NULL; + } + if (di_pre_stru.di_inp_buf) { + if (di_pre_stru.di_mem_buf_dup_p == di_pre_stru.di_inp_buf) + di_pre_stru.di_mem_buf_dup_p = NULL; + + queue_in(di_pre_stru.di_inp_buf, QUEUE_RECYCLE); + di_pre_stru.di_inp_buf = NULL; + } +} + +static void top_bot_config(struct di_buf_s *di_buf) +{ + vframe_t *vframe = di_buf->vframe; + + if (((invert_top_bot & 0x1) != 0) && (!is_progressive(vframe))) { + if (di_buf->invert_top_bot_flag == 0) { + if ( + (vframe->type & VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_TOP) { + vframe->type &= (~VIDTYPE_TYPEMASK); + vframe->type |= VIDTYPE_INTERLACE_BOTTOM; + } else { + vframe->type &= (~VIDTYPE_TYPEMASK); + vframe->type |= VIDTYPE_INTERLACE_TOP; + } + di_buf->invert_top_bot_flag = 1; + } + } +} + +static void pulldown_buf_init(struct di_buf_s *di_buf) +{ + di_buf->pulldown_mode = + PULL_DOWN_NORMAL; + di_buf->reg0_s = 0; + di_buf->reg0_e = 0; + di_buf->reg0_bmode = 0; + + di_buf->reg1_s = 0; + di_buf->reg1_e = 0; + di_buf->reg1_bmode = 0; + + di_buf->reg2_s = 0; + di_buf->reg2_e = 0; + di_buf->reg2_bmode = 0; + + di_buf->reg3_s = 0; + di_buf->reg3_e = 0; + di_buf->reg3_bmode = 0; +} + +static void pulldown_wnd_config(struct di_buf_s *di_buf) +{ + di_buf->reg0_s = dectres.rPstCYWnd0[0]; + di_buf->reg0_e = dectres.rPstCYWnd0[1]; + di_buf->reg1_s = dectres.rPstCYWnd1[0]; + di_buf->reg1_e = dectres.rPstCYWnd1[1]; + di_buf->reg2_s = dectres.rPstCYWnd2[0]; + di_buf->reg2_e = dectres.rPstCYWnd2[1]; + di_buf->reg3_s = dectres.rPstCYWnd3[0]; + di_buf->reg3_e = dectres.rPstCYWnd3[1]; + di_buf->reg0_bmode = dectres.rPstCYWnd0[2]; + di_buf->reg1_bmode = dectres.rPstCYWnd1[2]; + di_buf->reg2_bmode = dectres.rPstCYWnd2[2]; + di_buf->reg3_bmode = dectres.rPstCYWnd3[2]; + +} +struct FlmModReg_t flmreg; +unsigned int pulldown_enable = 1; +module_param(pulldown_enable, uint, 0644); +MODULE_PARM_DESC(pulldown_enable, "/n pulldonw mode result./n"); + +static unsigned int pldn_mod; +module_param(pldn_mod, uint, 0644); +MODULE_PARM_DESC(pldn_mod, "/n pulldonw mode result./n"); + +static unsigned int pldn_cmb0 = 1; +module_param(pldn_cmb0, uint, 0644); +MODULE_PARM_DESC(pldn_cmb0, "/n pulldonw combing result./n"); + +static unsigned int pldn_cmb1; +module_param(pldn_cmb1, uint, 0644); +MODULE_PARM_DESC(pldn_cmb1, "/n pulldonw combing result./n"); + +unsigned int field_count; + +int cmb_adpset_cnt; +module_param(cmb_adpset_cnt, int, 0664); + +unsigned int field_diff_rate; + +static unsigned int flm22_sure_num = 100; + +/* + * static unsigned int flmxx_sure_num = 50; + * module_param(flmxx_sure_num, uint, 0644); + * MODULE_PARM_DESC(flmxx_sure_num, "true film-xx/n"); + */ + +static unsigned int flm22_sure_smnum = 70; +static unsigned int flm22_ratio = 100; +/* 79 for iptv test pd22 ts */ +module_param_named(flm22_ratio, flm22_ratio, uint, 0644); +/* static unsigned int flmxx_sure_num[7] + * = {50, 50, 50, 50, 50, 50, 50}; + */ +static unsigned int flmxx_sure_num[7] = {20, 20, 20, 20, 20, 20, 20}; +static unsigned int flmxx_snum_adr = 7; +module_param_array(flmxx_sure_num, uint, &flmxx_snum_adr, 0664); + +static unsigned int flm22_glbpxlnum_rat = 4; /* 4/256 = 64 */ + +static unsigned int flm22_glbpxl_maxrow = 16; /* 16/256 = 16 */ +module_param(flm22_glbpxl_maxrow, uint, 0644); +MODULE_PARM_DESC(flm22_glbpxl_maxrow, "flm22_glbpxl_maxrow/n"); + +static unsigned int flm22_glbpxl_minrow = 3; /* 4/256 = 64 */ +module_param(flm22_glbpxl_minrow, uint, 0644); +MODULE_PARM_DESC(flm22_glbpxl_minrow, "flm22_glbpxl_minrow/n"); + +static unsigned int cmb_3point_rnum; +module_param(cmb_3point_rnum, uint, 0644); +MODULE_PARM_DESC(cmb_3point_rnum, "cmb_3point_rnum/n"); + +static unsigned int cmb_3point_rrat = 32; +module_param(cmb_3point_rrat, uint, 0644); +MODULE_PARM_DESC(cmb_3point_rrat, "cmb_3point_rrat/n"); + +static unsigned int pldn_calc_en = 1; +module_param(pldn_calc_en, uint, 0644); +MODULE_PARM_DESC(pldn_calc_en, "/n pulldonw calculation enable./n"); + +static bool combing_fix_en = true; +module_param_named(combing_fix_en, combing_fix_en, bool, 0664); + +static int cur_lev = 2; +module_param_named(combing_cur_lev, cur_lev, int, 0444); + +static void pre_de_done_buf_config(void) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + bool dynamic_flag = false; + int hHeight = di_pre_stru.di_nrwr_mif.end_y; + int wWidth = di_pre_stru.di_nrwr_mif.end_x; + int tTCNm; + bool flm32 = false; + bool flm22 = false; + bool flmxx = false; + int tb_chk_ret = 0, like_pulldown22_flag = 0; + static unsigned int frame_diff_avg; + unsigned int glb_frame_mot_num = 0; + unsigned int glb_field_mot_num = 0; + unsigned int mot_row = 0; + unsigned int mot_max = 0; + unsigned int flm22_surenum = flm22_sure_num; + unsigned int ntmp = 0; + + if (di_pre_stru.di_wr_buf) { + if (di_pre_stru.pre_throw_flag > 0) { + di_pre_stru.di_wr_buf->throw_flag = 1; + di_pre_stru.pre_throw_flag--; + } else { + di_pre_stru.di_wr_buf->throw_flag = 0; + } +#ifdef DET3D + if (di_pre_stru.di_wr_buf->vframe->trans_fmt == 0 && + di_pre_stru.det3d_trans_fmt != 0 && det3d_en) { + di_pre_stru.di_wr_buf->vframe->trans_fmt = + di_pre_stru.det3d_trans_fmt; + set3d_view(di_pre_stru.det3d_trans_fmt, + di_pre_stru.di_wr_buf->vframe); + } +#endif + if (!di_pre_rdma_enable) + di_pre_stru.di_post_wr_buf = di_pre_stru.di_wr_buf; + + if (di_pre_stru.cur_source_type == VFRAME_SOURCE_TYPE_OTHERS && + tff_bff_enable) { + tb_chk_ret = tff_bff_check((di_pre_stru.cur_height>>1), + di_pre_stru.cur_width); + di_pre_stru.di_post_wr_buf->privated &= (~0x3); + di_pre_stru.di_post_wr_buf->privated |= tb_chk_ret; + } + if (di_pre_stru.di_post_wr_buf) { + dynamic_flag = read_pulldown_info( + &(di_pre_stru.di_post_wr_buf->field_pd_info), + &(di_pre_stru.di_post_wr_buf->win_pd_info[0])); + glb_frame_mot_num = di_pre_stru.di_post_wr_buf-> + field_pd_info.frame_diff_num; + glb_field_mot_num = di_pre_stru.di_post_wr_buf-> + field_pd_info.field_diff_num; + di_pre_stru.static_frame_count = + dynamic_flag ? 0 : (di_pre_stru. + static_frame_count + 1); + if (di_pre_stru.static_frame_count > + static_pic_threshold) { + di_pre_stru.static_frame_count = + static_pic_threshold; + di_pre_stru.di_post_wr_buf->pulldown_mode = + PULL_DOWN_BLEND_0; + } else { + di_pre_stru.di_post_wr_buf->pulldown_mode = + PULL_DOWN_NORMAL; + } + if (combing_fix_en) + cur_lev = adaptive_combing_fixing( + glb_field_mot_num, + glb_frame_mot_num, + cur_lev, + di_force_bit_mode, + tTCNm, + like_pulldown22_flag, + &frame_diff_avg); + } + + tTCNm = 0; + if (!di_pre_stru.cur_prog_flag) { + /* always read and print data */ + read_new_pulldown_info(&flmreg); + /* read_new_pulldown_info(&flmreg); */ + if ((pldn_calc_en == 1) && pulldown_enable) { + dectres.rF22Flag = FlmVOFSftTop( + &(dectres.rCmb32Spcl), + dectres.rPstCYWnd0, + dectres.rPstCYWnd1, + dectres.rPstCYWnd2, + dectres.rPstCYWnd3, + dectres.rPstCYWnd4, + &(dectres.rFlmPstGCm), + &(dectres.rFlmSltPre), + &(dectres.rFlmPstMod), + flmreg.rROFldDif01, + flmreg.rROFrmDif02, + flmreg.rROCmbInf, + glb_frame_mot_num, + glb_field_mot_num, + &tTCNm, + &pd_param, + hHeight + 1, + wWidth + 1, + &frame_diff_avg); + + if (hHeight >= 289) /*full hd */ + tTCNm = tTCNm << 1; + if (tTCNm > hHeight) + tTCNm = hHeight; + + prt_flg = ((pr_pd >> 1) & 0x1); + if (prt_flg) { + sprintf(debug_str, "#Pst-Dbg:\n"); + sprintf(debug_str + strlen(debug_str), + "Mod=%d, Pre=%d, GCmb=%d, Lvl2=%d\n", + dectres.rFlmPstMod, + dectres.rFlmSltPre, + dectres.rFlmPstGCm, + dectres.rF22Flag); + + sprintf(debug_str + strlen(debug_str), + "N%03d: nd[%d~%d], [%d~%d], [%d~%d], [%d~%d]\n", + tTCNm, + dectres.rPstCYWnd0[0], + dectres.rPstCYWnd0[1], + dectres.rPstCYWnd1[0], + dectres.rPstCYWnd1[1], + dectres.rPstCYWnd2[0], + dectres.rPstCYWnd2[1], + dectres.rPstCYWnd3[0], + dectres.rPstCYWnd3[1]); + + pr_info("%s", debug_str); + } + } + + if (pulldown_enable && di_pre_stru.di_post_wr_buf) { + /* refresh, default setting */ + pulldown_buf_init(di_pre_stru.di_post_wr_buf); + } + if (dectres.rFlmPstMod == 1) + like_pulldown22_flag = dectres.rF22Flag; + else + like_pulldown22_flag = 0; + + if ((pr_pd >> 1) & 0x1) + pr_info("fld_dif_rat=%d\n", + field_diff_rate); + if ((dectres.rF22Flag >= + (cmb_3point_rnum + field_diff_rate)) && + (tTCNm > + (hHeight * cmb_3point_rrat >> 8))) { + if ((pr_pd >> 1) & 0x1) + pr_info("coeff-3-point enabled\n"); + } + if (pulldown_enable == 1 && dectres.rFlmPstMod != 0 + && di_pre_stru.di_post_wr_buf) { + flm32 = (dectres.rFlmPstMod == 2 && + dectres.rFlmPstGCm == 0); + + ntmp = (glb_frame_mot_num + glb_field_mot_num) / + (wWidth + 1); + if (flm22_sure_num > ntmp + flm22_sure_smnum) + flm22_surenum = flm22_sure_num - ntmp; + else + flm22_surenum = flm22_sure_smnum; + + if (cmb_adpset_cnt > 0) + pr_info("flm22_surenum = %2d\n", + flm22_surenum); + if (dectres.rFlmPstMod == 1) { + mot_row = glb_frame_mot_num * + flm22_glbpxlnum_rat / (wWidth + 1); + mot_max = (flm22_glbpxl_maxrow * + hHeight + 128) >> 8; + if ((pr_pd >> 1) & 0x1) + pr_info("dejaggies level=%3d - (%02d - %02d)\n", + dectres.rF22Flag, + mot_max, mot_row); + + if (mot_row < mot_max) { + if (dectres.rF22Flag > + (mot_max - mot_row)) + dectres.rF22Flag -= + (mot_max - mot_row); + else + dectres.rF22Flag = 0; + + if (mot_row <= flm22_glbpxl_minrow) + dectres.rFlmPstMod = 0; + } + } + + flm22 = (dectres.rFlmPstMod == 1 && + dectres.rF22Flag >= flm22_surenum); + if (dectres.rFlmPstMod >= 4) + flmxx = (dectres.rF22Flag >= + flmxx_sure_num[dectres.rFlmPstMod - 4]); + else + flmxx = 0; + + /* 2-2 force */ + if ((pldn_mod == 0) && + (flm32 || flm22 || flmxx)) { + if (dectres.rFlmSltPre == 1) + di_pre_stru.di_post_wr_buf + ->pulldown_mode = + PULL_DOWN_BLEND_0; + else { + di_pre_stru.di_post_wr_buf + ->pulldown_mode = + PULL_DOWN_BLEND_2; + } + } else if (pldn_mod == 1) { + if (dectres.rFlmSltPre == 1) + di_pre_stru.di_post_wr_buf + ->pulldown_mode = + PULL_DOWN_BLEND_0; + else + di_pre_stru.di_post_wr_buf + ->pulldown_mode = + PULL_DOWN_BLEND_2; + } else { + di_pre_stru.di_post_wr_buf-> + pulldown_mode = + PULL_DOWN_NORMAL; + } + + if (flm32 && (pldn_cmb0 == 1)) { + pulldown_wnd_config( + di_pre_stru.di_post_wr_buf); + } else if (dectres.rF22Flag > 1 && + dectres.rFlmPstMod == 1 && + pldn_cmb0 == 1) { + /* SRSHARP0_SHARP_SR2_CTRL */ + /* SRSHARP0_SHARP_DEJ2_MISC */ + /* SRSHARP0_SHARP_DEJ1_MISC */ + + if ((pr_pd >> 1) & 0x1) + pr_info("dejaggies level= %3d\n", + dectres.rF22Flag); + } else if (dectres.rFlmPstGCm == 0 && + pldn_cmb0 > 1 && pldn_cmb0 <= 5) { + pulldown_wnd_config( + di_pre_stru.di_post_wr_buf); + /* 1-->only film-mode + * 2-->windows-->mtn + * 3-->windows-->detected + * 4-->windows-->di + */ + /* pldn_cmb0 == 2 + * setting in pulldown wnd config + */ + if (pldn_cmb0 == 3) { + di_pre_stru.di_post_wr_buf-> + reg0_bmode = 3; + di_pre_stru.di_post_wr_buf-> + reg1_bmode = 3; + di_pre_stru.di_post_wr_buf-> + reg2_bmode = 3; + di_pre_stru.di_post_wr_buf-> + reg3_bmode = 3; + } else if (pldn_cmb0 == 4) { + di_pre_stru.di_post_wr_buf-> + reg0_bmode = 2; + di_pre_stru.di_post_wr_buf-> + reg1_bmode = 2; + di_pre_stru.di_post_wr_buf-> + reg2_bmode = 2; + di_pre_stru.di_post_wr_buf-> + reg3_bmode = 2; + } else if (pldn_cmb0 == 5) { + di_pre_stru. + di_post_wr_buf->reg3_s = 0; + di_pre_stru. + di_post_wr_buf->reg3_e = 60; + di_pre_stru. + di_post_wr_buf->reg3_bmode = 0; + } + } + /* else pldn_cmb0==0 (Nothing) */ + if ((dectres.rFlmPstGCm == 1) && (pldn_cmb1 > 0) + && (pldn_cmb1 <= 5)) { + pulldown_wnd_config( + di_pre_stru.di_post_wr_buf); + /* + * 1-->normal set in pulldown + * wnd config func + */ + if (pldn_cmb1 == 2) { + di_pre_stru. + di_post_wr_buf->reg0_bmode = 3; + di_pre_stru. + di_post_wr_buf->reg1_bmode = 3; + di_pre_stru. + di_post_wr_buf->reg2_bmode = 3; + di_pre_stru. + di_post_wr_buf->reg3_bmode = 3; + } else if (pldn_cmb1 == 3) { + di_pre_stru. + di_post_wr_buf->reg0_bmode = 2; + di_pre_stru. + di_post_wr_buf->reg1_bmode = 2; + di_pre_stru. + di_post_wr_buf->reg2_bmode = 2; + di_pre_stru. + di_post_wr_buf->reg3_bmode = 2; + } else if (pldn_cmb1 == 4) { + di_pre_stru. + di_post_wr_buf->reg2_s = 202; + di_pre_stru. + di_post_wr_buf->reg2_e = 222; + di_pre_stru. + di_post_wr_buf->reg2_bmode = 0; + } + } + } else if ((pldn_cmb0 == 6) && (pldn_cmb1 == 6)) { + di_pre_stru.di_post_wr_buf->reg1_s = 60; + di_pre_stru.di_post_wr_buf->reg1_e = 180; + di_pre_stru.di_post_wr_buf->reg1_bmode = 0; + } + } + field_count++; + if (field_count == 0x7fffffff) + field_count = 3; + + if (di_pre_stru.cur_prog_flag) { + if (di_pre_stru.prog_proc_type == 0) { + /* di_mem_buf_dup->vfrme + * is either local vframe, + * or bot field of vframe from in_list + */ + di_pre_stru.di_mem_buf_dup_p->pre_ref_count = 0; + di_pre_stru.di_mem_buf_dup_p + = di_pre_stru.di_chan2_buf_dup_p; + di_pre_stru.di_chan2_buf_dup_p + = di_pre_stru.di_wr_buf; +#ifdef DI_BUFFER_DEBUG + di_print("%s:set di_mem to di_chan2,", + __func__); + di_print("%s:set di_chan2 to di_wr_buf\n", + __func__); +#endif + } else { + di_pre_stru.di_mem_buf_dup_p->pre_ref_count = 0; + /*recycle the progress throw buffer*/ + if (di_pre_stru.di_wr_buf->throw_flag) { + di_pre_stru.di_wr_buf-> + pre_ref_count = 0; + di_pre_stru.di_mem_buf_dup_p = NULL; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s set throw %s[%d] pre_ref_count to 0.\n", + __func__, + vframe_type_name[di_pre_stru.di_wr_buf->type], + di_pre_stru.di_wr_buf->index); +#endif + } else { + di_pre_stru.di_mem_buf_dup_p + = di_pre_stru.di_wr_buf; + } +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: set di_mem_buf_dup_p to di_wr_buf\n", + __func__); +#endif + } + + di_pre_stru.di_wr_buf->seq + = di_pre_stru.pre_ready_seq++; + di_pre_stru.di_wr_buf->post_ref_count = 0; + di_pre_stru.di_wr_buf->left_right + = di_pre_stru.left_right; + if (di_pre_stru.source_change_flag) { + di_pre_stru.di_wr_buf->new_format_flag = 1; + di_pre_stru.source_change_flag = 0; + } else { + di_pre_stru.di_wr_buf->new_format_flag = 0; + } + if (bypass_state == 1) { + di_pre_stru.di_wr_buf->new_format_flag = 1; + bypass_state = 0; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s:bypass_state->0, is_bypass() %d\n", + __func__, is_bypass(NULL)); + di_print( + "trick_mode %d bypass_all %d\n", + trick_mode, bypass_all); +#endif + } + if (di_pre_stru.di_post_wr_buf) + queue_in(di_pre_stru.di_post_wr_buf, + QUEUE_PRE_READY); +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: %s[%d] => pre_ready_list\n", __func__, + vframe_type_name[di_pre_stru.di_wr_buf->type], + di_pre_stru.di_wr_buf->index); +#endif + if (di_pre_stru.di_wr_buf) { + if (di_pre_rdma_enable) + di_pre_stru.di_post_wr_buf = + di_pre_stru.di_wr_buf; + else + di_pre_stru.di_post_wr_buf = NULL; + di_pre_stru.di_wr_buf = NULL; + } + } else { + di_pre_stru.di_mem_buf_dup_p->pre_ref_count = 0; + di_pre_stru.di_mem_buf_dup_p = NULL; + if (di_pre_stru.di_chan2_buf_dup_p) { + di_pre_stru.di_mem_buf_dup_p = + di_pre_stru.di_chan2_buf_dup_p; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: di_mem_buf_dup_p = di_chan2_buf_dup_p\n", + __func__); +#endif + } + di_pre_stru.di_chan2_buf_dup_p = di_pre_stru.di_wr_buf; + + if (di_pre_stru.di_wr_buf->post_proc_flag == 2) { + /* add dummy buf, will not be displayed */ + if (!queue_empty(QUEUE_LOCAL_FREE)) { + struct di_buf_s *di_buf_tmp; + + di_buf_tmp = + get_di_buf_head(QUEUE_LOCAL_FREE); + if (di_buf_tmp) { + queue_out(di_buf_tmp); + di_buf_tmp->pre_ref_count = 0; + di_buf_tmp->post_ref_count = 0; + di_buf_tmp->post_proc_flag = 3; + di_buf_tmp->new_format_flag = 0; + queue_in( + di_buf_tmp, + QUEUE_PRE_READY); + } +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: dummy %s[%d] => pre_ready_list\n", + __func__, + vframe_type_name[di_buf_tmp->type], + di_buf_tmp->index); +#endif + } + } + di_pre_stru.di_wr_buf->seq = + di_pre_stru.pre_ready_seq++; + di_pre_stru.di_wr_buf->left_right = + di_pre_stru.left_right; + di_pre_stru.di_wr_buf->post_ref_count = 0; + if (di_pre_stru.source_change_flag) { + di_pre_stru.di_wr_buf->new_format_flag = 1; + di_pre_stru.source_change_flag = 0; + } else { + di_pre_stru.di_wr_buf->new_format_flag = 0; + } + if (bypass_state == 1) { + di_pre_stru.di_wr_buf->new_format_flag = 1; + bypass_state = 0; + +#ifdef DI_BUFFER_DEBUG + di_print( + "%s:bypass_state->0, is_bypass() %d\n", + __func__, is_bypass(NULL)); + di_print( + "trick_mode %d bypass_all %d\n", + trick_mode, bypass_all); +#endif + } + + if (di_pre_stru.di_post_wr_buf) + queue_in(di_pre_stru.di_post_wr_buf, + QUEUE_PRE_READY); + + di_print("%s: %s[%d] => pre_ready_list\n", __func__, + vframe_type_name[di_pre_stru.di_wr_buf->type], + di_pre_stru.di_wr_buf->index); + + if (di_pre_stru.di_wr_buf) { + if (di_pre_rdma_enable) + di_pre_stru.di_post_wr_buf = + di_pre_stru.di_wr_buf; + else + di_pre_stru.di_post_wr_buf = NULL; + di_pre_stru.di_wr_buf = NULL; + } + } + } + + if (di_pre_stru.di_post_inp_buf && di_pre_rdma_enable) { +#ifdef DI_BUFFER_DEBUG + di_print("%s: %s[%d] => recycle_list\n", __func__, + vframe_type_name[di_pre_stru.di_post_inp_buf->type], + di_pre_stru.di_post_inp_buf->index); +#endif + di_lock_irqfiq_save(irq_flag2, fiq_flag); + queue_in(di_pre_stru.di_post_inp_buf, QUEUE_RECYCLE); + di_pre_stru.di_post_inp_buf = NULL; + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + } + if (di_pre_stru.di_inp_buf) { + if (!di_pre_rdma_enable) { +#ifdef DI_BUFFER_DEBUG + di_print("%s: %s[%d] => recycle_list\n", __func__, + vframe_type_name[di_pre_stru.di_inp_buf->type], + di_pre_stru.di_inp_buf->index); +#endif + di_lock_irqfiq_save(irq_flag2, fiq_flag); + queue_in(di_pre_stru.di_inp_buf, QUEUE_RECYCLE); + di_pre_stru.di_inp_buf = NULL; + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + } else { + di_pre_stru.di_post_inp_buf = di_pre_stru.di_inp_buf; + di_pre_stru.di_inp_buf = NULL; + } + } +} + +static void recycle_vframe_type_pre(struct di_buf_s *di_buf) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + + di_lock_irqfiq_save(irq_flag2, fiq_flag); + + queue_in(di_buf, QUEUE_RECYCLE); + + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); +} +/* + * it depend on local buffer queue type is 2 + */ +static int peek_free_linked_buf(void) +{ + struct di_buf_s *p = NULL; + int itmp, p_index = -2; + + if (list_count(QUEUE_LOCAL_FREE) < 2) + return -1; + + queue_for_each_entry(p, ptmp, QUEUE_LOCAL_FREE, list) { + if (abs(p->index - p_index) == 1) + return min(p->index, p_index); + p_index = p->index; + } + return -1; +} +/* + * it depend on local buffer queue type is 2 + */ +static struct di_buf_s *get_free_linked_buf(int idx) +{ + struct di_buf_s *di_buf = NULL, *di_buf_linked = NULL; + int pool_idx = 0, di_buf_idx = 0; + + queue_t *q = &(queue[QUEUE_LOCAL_FREE]); + + if (list_count(QUEUE_LOCAL_FREE) < 2) + return NULL; + if (q->pool[idx] != 0 && q->pool[idx + 1] != 0) { + pool_idx = ((q->pool[idx] >> 8) & 0xff) - 1; + di_buf_idx = q->pool[idx] & 0xff; + if (pool_idx < VFRAME_TYPE_NUM) { + if (di_buf_idx < di_buf_pool[pool_idx].size) { + di_buf = &(di_buf_pool[pool_idx]. + di_buf_ptr[di_buf_idx]); + queue_out(di_buf); + } + } + pool_idx = ((q->pool[idx + 1] >> 8) & 0xff) - 1; + di_buf_idx = q->pool[idx + 1] & 0xff; + if (pool_idx < VFRAME_TYPE_NUM) { + if (di_buf_idx < di_buf_pool[pool_idx].size) { + di_buf_linked = &(di_buf_pool[pool_idx]. + di_buf_ptr[di_buf_idx]); + queue_out(di_buf_linked); + } + } + di_buf->di_wr_linked_buf = di_buf_linked; + } + return di_buf; +} + +static bool pre_de_proc(void) +{ + int in_buf_num = 0, i = 0; + struct vframe_s *vframe = vf_peek(VFM_NAME); + + if (!vframe || di_blocking) + return false; + + if (is_bypass(vframe)) { + /* some provider has problem if receiver + * get all buffers of provider + */ + cur_lev = 0; + for (i = 0; i < MAX_IN_BUF_NUM; i++) + if (vframe_in[i] != NULL) + in_buf_num++; + if (in_buf_num > BYPASS_GET_MAX_BUF_NUM +#ifdef DET3D + && (di_pre_stru.vframe_interleave_flag == 0) +#endif + ) + return false; + } +#ifdef CHECK_VDIN_BUF_ERROR + if (is_from_vdin(vframe)) { + if (vframe->canvas0Addr == + Rd_reg_bits((VDIN_WR_CTRL + 0), WR_CANVAS_BIT, + WR_CANVAS_WID)) + same_w_r_canvas_count++; +#ifdef RUN_DI_PROCESS_IN_IRQ + di_pre_stru.vdin2nr = is_input2pre(); +#endif + } +#endif + if ( + (vframe->source_type == VFRAME_SOURCE_TYPE_OTHERS) && + (vframe->width % 2 == 1)) { + force_width = vframe->width - 1; + if (force_width != (vframe->width - 1)) + pr_info("DI: force source width %u to even num %d.\n", + vframe->width, force_width); + } else { + force_width = 0; + } + + return true; + +} + +static unsigned char pre_de_buf_config(void) +{ + struct di_buf_s *di_buf = NULL; + vframe_t *vframe; + int di_linked_buf_idx = -1; + unsigned char change_type = 0; + + if ((list_count(QUEUE_IN_FREE) < 2 && (!di_pre_stru.di_inp_buf_next)) || + (queue_empty(QUEUE_LOCAL_FREE))) + return 0; + + if (di_pre_stru.prog_proc_type == 2) { + di_linked_buf_idx = peek_free_linked_buf(); + if (di_linked_buf_idx == -1 && used_post_buf_index != -1) { + recycle_keep_buffer(); + pr_info("%s: recycle keep buffer for peek null linked buf\n", + __func__); + return 0; + } + } + + if (!pre_de_proc()) + return 0; + + if (di_pre_stru.di_inp_buf_next) { + di_pre_stru.di_inp_buf = di_pre_stru.di_inp_buf_next; + di_pre_stru.di_inp_buf_next = NULL; +#ifdef DI_BUFFER_DEBUG + di_print("%s: di_inp_buf_next %s[%d] => di_inp_buf\n", + __func__, + vframe_type_name[di_pre_stru.di_inp_buf->type], + di_pre_stru.di_inp_buf->index); +#endif + if (di_pre_stru.di_mem_buf_dup_p == NULL) {/* use n */ + di_pre_stru.di_mem_buf_dup_p = di_pre_stru.di_inp_buf; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: set di_mem_buf_dup_p to be di_inp_buf\n", + __func__); +#endif + } + } else { + /* check if source change */ + + vframe = vf_get(VFM_NAME); + + if (vframe == NULL) + return 0; + di_print("DI: get vframe[0x%p] from frontend %u ms.\n", + vframe, + jiffies_to_msecs(jiffies_64 - vframe->ready_jiffies64)); + + vframe->prog_proc_config = (prog_proc_config&0x20) >> 5; + di_pre_stru.source_trans_fmt = vframe->trans_fmt; + di_pre_stru.left_right = di_pre_stru.left_right ? 0 : 1; + di_pre_stru.invert_flag = + (vframe->type & TB_DETECT_MASK) ? true : false; + vframe->type &= ~TB_DETECT_MASK; + + if (((invert_top_bot & 0x2) != 0 || + di_pre_stru.invert_flag) && + (!is_progressive(vframe))) { + if ( + (vframe->type & VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_TOP) { + vframe->type &= (~VIDTYPE_TYPEMASK); + vframe->type |= VIDTYPE_INTERLACE_BOTTOM; + } else { + vframe->type &= (~VIDTYPE_TYPEMASK); + vframe->type |= VIDTYPE_INTERLACE_TOP; + } + } + + if (force_width) + vframe->width = force_width; + + /* backup frame motion info */ + vframe->combing_cur_lev = cur_lev; + + di_print("%s: vf_get => 0x%p\n", __func__, vframe); + + provider_vframe_level--; + di_buf = get_di_buf_head(QUEUE_IN_FREE); + + if (check_di_buf(di_buf, 10)) + return 0; + + if (di_log_flag & DI_LOG_VFRAME) + dump_vframe(vframe); + +#ifdef SUPPORT_MPEG_TO_VDIN + if ( + (!is_from_vdin(vframe)) && + (vframe->sig_fmt == TVIN_SIG_FMT_NULL) && + mpeg2vdin_flag) { + struct vdin_arg_s vdin_arg; + struct vdin_v4l2_ops_s *vdin_ops = get_vdin_v4l2_ops(); + + vdin_arg.cmd = VDIN_CMD_GET_HISTGRAM; + vdin_arg.private = (unsigned int)vframe; + if (vdin_ops->tvin_vdin_func) + vdin_ops->tvin_vdin_func(0, &vdin_arg); + } +#endif + memcpy(di_buf->vframe, vframe, sizeof(vframe_t)); + + di_buf->vframe->private_data = di_buf; + vframe_in[di_buf->index] = vframe; + di_buf->seq = di_pre_stru.in_seq; + di_pre_stru.in_seq++; + queue_out(di_buf); + change_type = is_source_change(vframe); + /* source change, when i mix p,force p as i*/ + if (change_type == 1 || (change_type == 2 && + di_pre_stru.cur_prog_flag == 1)) { + if (di_pre_stru.di_mem_buf_dup_p) { + /*avoid only 2 i field then p field*/ + if ( + (di_pre_stru.cur_prog_flag == 0) && + use_2_interlace_buff) + di_pre_stru.di_mem_buf_dup_p-> + post_proc_flag = -1; + di_pre_stru.di_mem_buf_dup_p->pre_ref_count = 0; + di_pre_stru.di_mem_buf_dup_p = NULL; + } + if (di_pre_stru.di_chan2_buf_dup_p) { + /*avoid only 1 i field then p field*/ + if ( + (di_pre_stru.cur_prog_flag == 0) && + use_2_interlace_buff) + di_pre_stru.di_chan2_buf_dup_p-> + post_proc_flag = -1; + di_pre_stru.di_chan2_buf_dup_p->pre_ref_count = + 0; + di_pre_stru.di_chan2_buf_dup_p = NULL; + } + /* force recycle keep buffer when switch source */ + if (used_post_buf_index != -1) { + if (di_buf_post[used_post_buf_index].vframe + ->source_type != + di_buf->vframe->source_type) { + recycle_keep_buffer(); + pr_info("%s: source type changed!!!\n", + __func__); + } + } + pr_info( + "%s: source change: 0x%x/%d/%d/%d=>0x%x/%d/%d/%d\n", + __func__, + di_pre_stru.cur_inp_type, + di_pre_stru.cur_width, + di_pre_stru.cur_height, + di_pre_stru.cur_source_type, + di_buf->vframe->type, + di_buf->vframe->width, + di_buf->vframe->height, + di_buf->vframe->source_type); + di_pre_stru.cur_width = di_buf->vframe->width; + di_pre_stru.cur_height = di_buf->vframe->height; + di_pre_stru.cur_prog_flag = + is_progressive(di_buf->vframe); + if (di_pre_stru.cur_prog_flag) { + if ((use_2_interlace_buff) && + !(prog_proc_config & 0x10)) + di_pre_stru.prog_proc_type = 2; + else + di_pre_stru.prog_proc_type + = prog_proc_config & 0x10; + } else + di_pre_stru.prog_proc_type = 0; + di_pre_stru.cur_inp_type = di_buf->vframe->type; + di_pre_stru.cur_source_type = + di_buf->vframe->source_type; + di_pre_stru.cur_sig_fmt = di_buf->vframe->sig_fmt; + di_pre_stru.orientation = di_buf->vframe->video_angle; + di_pre_stru.source_change_flag = 1; + di_pre_stru.same_field_source_flag = 0; +#if defined(NEW_DI_TV) + di_set_para_by_tvinfo(vframe); +#endif +#ifdef SUPPORT_MPEG_TO_VDIN + if ((!is_from_vdin(vframe)) && + (vframe->sig_fmt == TVIN_SIG_FMT_NULL) && + (mpeg2vdin_en)) { + struct vdin_arg_s vdin_arg; + struct vdin_v4l2_ops_s *vdin_ops = + get_vdin_v4l2_ops(); + vdin_arg.cmd = VDIN_CMD_MPEGIN_START; + vdin_arg.h_active = di_pre_stru.cur_width; + vdin_arg.v_active = di_pre_stru.cur_height; + if (vdin_ops->tvin_vdin_func) + vdin_ops->tvin_vdin_func(0, &vdin_arg); + mpeg2vdin_flag = 1; + } +#endif +#ifdef NEW_DI_V1 + di_pre_stru.field_count_for_cont = 0; +#endif + } else if (di_pre_stru.cur_prog_flag == 0) { + /* check if top/bot interleaved */ + if (change_type == 2) + /* source is i interleaves p fields */ + di_pre_stru.force_interlace = true; + if ((di_pre_stru.cur_inp_type & + VIDTYPE_TYPEMASK) == (di_buf->vframe->type & + VIDTYPE_TYPEMASK)) { +#ifdef CHECK_VDIN_BUF_ERROR + if ((di_buf->vframe->type & + VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_TOP) + same_field_top_count++; + else + same_field_bot_count++; +#endif + if (di_pre_stru.same_field_source_flag < + same_field_source_flag_th) { + /* some source's filed + * is top or bot always + */ + di_pre_stru.same_field_source_flag++; + + if (skip_wrong_field && + is_from_vdin(di_buf->vframe)) { + recycle_vframe_type_pre( + di_buf); + return 0; + } + } + + } else + di_pre_stru.same_field_source_flag = 0; + di_pre_stru.cur_inp_type = di_buf->vframe->type; + } else { + di_pre_stru.same_field_source_flag = 0; + di_pre_stru.cur_inp_type = di_buf->vframe->type; + } + + if (is_bypass(di_buf->vframe)) { + /* bypass progressive */ + di_buf->seq = di_pre_stru.pre_ready_seq++; + di_buf->post_ref_count = 0; + cur_lev = 0; + if (di_pre_stru.source_change_flag) { + di_buf->new_format_flag = 1; + di_pre_stru.source_change_flag = 0; + } else { + di_buf->new_format_flag = 0; + } + + if (bypass_state == 0) { + if (di_pre_stru.di_mem_buf_dup_p) { + di_pre_stru.di_mem_buf_dup_p-> + pre_ref_count = 0; + di_pre_stru.di_mem_buf_dup_p = NULL; + } + if (di_pre_stru.di_chan2_buf_dup_p) { + di_pre_stru.di_chan2_buf_dup_p-> + pre_ref_count = 0; + di_pre_stru.di_chan2_buf_dup_p = NULL; + } + + if (di_pre_stru.di_wr_buf) { + di_pre_stru.di_wr_buf->pre_ref_count = + 0; + di_pre_stru.di_wr_buf->post_ref_count = + 0; + recycle_vframe_type_pre( + di_pre_stru.di_wr_buf); +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: %s[%d] => recycle_list\n", + __func__, + vframe_type_name[di_pre_stru. + di_wr_buf->type], + di_pre_stru.di_wr_buf->index); +#endif + di_pre_stru.di_wr_buf = NULL; + } + + di_buf->new_format_flag = 1; + bypass_state = 1; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s:bypass_state = 1, is_bypass() %d\n", + __func__, is_bypass(NULL)); + di_print( + "trick_mode %d bypass_all %d\n", + trick_mode, bypass_all); +#endif + } + + top_bot_config(di_buf); + /*if previous isn't bypass post_wr_buf not recycled */ + if (di_pre_stru.di_post_wr_buf && di_pre_rdma_enable) { + queue_in( + di_pre_stru.di_post_inp_buf, + QUEUE_RECYCLE); + di_pre_stru.di_post_inp_buf = NULL; + } + + if ( + (bypass_pre & 0x2) && + !di_pre_stru.cur_prog_flag) + di_buf->post_proc_flag = -2; + else + di_buf->post_proc_flag = 0; + + queue_in(di_buf, QUEUE_PRE_READY); +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: %s[%d] => pre_ready_list\n", __func__, + vframe_type_name[di_buf->type], di_buf->index); +#endif + return 0; + } else if (is_progressive(di_buf->vframe)) { + if ( + is_handle_prog_frame_as_interlace(vframe) && + (is_progressive(vframe))) { + struct di_buf_s *di_buf_tmp = NULL; + + vframe_in[di_buf->index] = NULL; + di_buf->vframe->type &= + (~VIDTYPE_TYPEMASK); + di_buf->vframe->type |= + VIDTYPE_INTERLACE_TOP; + di_buf->post_proc_flag = 0; + + di_buf_tmp = + get_di_buf_head(QUEUE_IN_FREE); + if (check_di_buf(di_buf_tmp, 10)) { + recycle_vframe_type_pre(di_buf); + pr_err("DI:no free in_buffer for progressive skip.\n"); + return 0; + } + di_buf_tmp->vframe->private_data + = di_buf_tmp; + di_buf_tmp->seq = di_pre_stru.in_seq; + di_pre_stru.in_seq++; + queue_out(di_buf_tmp); + vframe_in[di_buf_tmp->index] = vframe; + memcpy( + di_buf_tmp->vframe, vframe, + sizeof(vframe_t)); + di_pre_stru.di_inp_buf_next + = di_buf_tmp; + di_buf_tmp->vframe->type + &= (~VIDTYPE_TYPEMASK); + di_buf_tmp->vframe->type + |= VIDTYPE_INTERLACE_BOTTOM; + di_buf_tmp->post_proc_flag = 0; + + di_pre_stru.di_inp_buf = di_buf; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: %s[%d] => di_inp_buf; %s[%d] => di_inp_buf_next\n", + __func__, + vframe_type_name[di_buf->type], + di_buf->index, + vframe_type_name[di_buf_tmp->type], + di_buf_tmp->index); +#endif + if (di_pre_stru.di_mem_buf_dup_p == NULL) { + di_pre_stru.di_mem_buf_dup_p = di_buf; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: set di_mem_buf_dup_p to be di_inp_buf\n", + __func__); +#endif + } + } else { + di_buf->post_proc_flag = 0; + if ((prog_proc_config & 0x40) || + di_pre_stru.force_interlace) + di_buf->post_proc_flag = 1; + di_pre_stru.di_inp_buf = di_buf; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: %s[%d] => di_inp_buf\n", + __func__, + vframe_type_name[di_buf->type], + di_buf->index); +#endif + if ( + di_pre_stru.di_mem_buf_dup_p == NULL) { + /* use n */ + di_pre_stru.di_mem_buf_dup_p + = di_buf; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: set di_mem_buf_dup_p to be di_inp_buf\n", + __func__); +#endif + } + } + } else { +#ifdef NEW_DI_V1 + if ( + di_pre_stru.di_chan2_buf_dup_p == NULL) { + di_pre_stru.field_count_for_cont = 0; + /* ignore contp2rd and contprd */ + } +#endif + di_buf->post_proc_flag = 1; + di_pre_stru.di_inp_buf = di_buf; + di_print("%s: %s[%d] => di_inp_buf\n", __func__, + vframe_type_name[di_buf->type], di_buf->index); + + if (di_pre_stru.di_mem_buf_dup_p == NULL) {/* use n */ + di_pre_stru.di_mem_buf_dup_p = di_buf; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: set di_mem_buf_dup_p to be di_inp_buf\n", + __func__); +#endif + } + } + } + + /* di_wr_buf */ + if (di_pre_stru.prog_proc_type == 2) { + di_linked_buf_idx = peek_free_linked_buf(); + if (di_linked_buf_idx != -1) + di_buf = get_free_linked_buf(di_linked_buf_idx); + else + di_buf = NULL; + if (di_buf == NULL) { + /* recycle_vframe_type_pre(di_pre_stru.di_inp_buf); + *save for next process + */ + recycle_keep_buffer(); + di_pre_stru.di_inp_buf_next = di_pre_stru.di_inp_buf; + return 0; + } + di_buf->post_proc_flag = 0; + di_buf->di_wr_linked_buf->pre_ref_count = 0; + di_buf->di_wr_linked_buf->post_ref_count = 0; + di_buf->canvas_config_flag = 1; + } else { + di_buf = get_di_buf_head(QUEUE_LOCAL_FREE); + if (check_di_buf(di_buf, 11)) { + /* recycle_keep_buffer(); + * pr_dbg("%s:recycle keep buffer\n", __func__); + */ + recycle_vframe_type_pre(di_pre_stru.di_inp_buf); + return 0; + } + queue_out(di_buf); + if (di_pre_stru.prog_proc_type & 0x10) + di_buf->canvas_config_flag = 1; + else + di_buf->canvas_config_flag = 2; + di_buf->di_wr_linked_buf = NULL; + } + + di_pre_stru.di_wr_buf = di_buf; + di_pre_stru.di_wr_buf->pre_ref_count = 1; + +#ifdef DI_BUFFER_DEBUG + di_print("%s: %s[%d] => di_wr_buf\n", __func__, + vframe_type_name[di_buf->type], di_buf->index); + if (di_buf->di_wr_linked_buf) + di_print("%s: linked %s[%d] => di_wr_buf\n", __func__, + vframe_type_name[di_buf->di_wr_linked_buf->type], + di_buf->di_wr_linked_buf->index); +#endif + + memcpy(di_buf->vframe, + di_pre_stru.di_inp_buf->vframe, sizeof(vframe_t)); + di_buf->vframe->private_data = di_buf; + di_buf->vframe->canvas0Addr = di_buf->nr_canvas_idx; + di_buf->vframe->canvas1Addr = di_buf->nr_canvas_idx; + /* set vframe bit info */ + di_buf->vframe->bitdepth &= ~(BITDEPTH_YMASK); + di_buf->vframe->bitdepth &= ~(FULL_PACK_422_MODE); + if (di_force_bit_mode == 10) { + di_buf->vframe->bitdepth |= (BITDEPTH_Y10); + if (full_422_pack) + di_buf->vframe->bitdepth |= (FULL_PACK_422_MODE); + } else + di_buf->vframe->bitdepth |= (BITDEPTH_Y8); + + if (di_pre_stru.prog_proc_type) { + di_buf->vframe->type = VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD; + if (di_pre_stru.cur_inp_type & VIDTYPE_PRE_INTERLACE) + di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE; + } else { + if ( + ((di_pre_stru.di_inp_buf->vframe->type & + VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_TOP)) + di_buf->vframe->type = VIDTYPE_INTERLACE_TOP | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD; + else + di_buf->vframe->type = VIDTYPE_INTERLACE_BOTTOM | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD; + } + +/* */ + if (is_bypass_post()) { + if (bypass_post_state == 0) + di_pre_stru.source_change_flag = 1; + + bypass_post_state = 1; + } else { + if (bypass_post_state) + di_pre_stru.source_change_flag = 1; + + bypass_post_state = 0; + } + +/* if(is_progressive(di_pre_stru.di_inp_buf->vframe)){ */ + if (di_pre_stru.di_inp_buf->post_proc_flag == 0) { + di_pre_stru.enable_mtnwr = 0; + di_pre_stru.enable_pulldown_check = 0; + di_buf->post_proc_flag = 0; + } else if (bypass_post_state) { + di_pre_stru.enable_mtnwr = 0; + di_pre_stru.enable_pulldown_check = 0; + di_buf->post_proc_flag = 0; + } else { + if (di_pre_stru.di_chan2_buf_dup_p == NULL) { + di_pre_stru.enable_mtnwr = 0; + di_pre_stru.enable_pulldown_check = 0; + di_buf->post_proc_flag = 2; + } else { + di_pre_stru.enable_mtnwr = 1; + di_buf->post_proc_flag = 1; + di_pre_stru.enable_pulldown_check = + di_pre_stru.cur_prog_flag ? 0 : 1; + } + } + +#ifndef USE_LIST + if ((di_pre_stru.di_mem_buf_dup_p == di_pre_stru.di_wr_buf) || + (di_pre_stru.di_chan2_buf_dup_p == di_pre_stru.di_wr_buf)) { + pr_dbg("+++++++++++++++++++++++\n"); + if (recovery_flag == 0) + recovery_log_reason = 12; + + recovery_flag++; + return 0; + } +#endif + return 1; +} + +static int check_recycle_buf(void) +{ + struct di_buf_s *di_buf = NULL;/* , *ptmp; */ + int itmp; + int ret = 0; + + if (di_blocking) + return ret; + queue_for_each_entry(di_buf, ptmp, QUEUE_RECYCLE, list) { + if ((di_buf->pre_ref_count == 0) && + (di_buf->post_ref_count == 0)) { + if (di_buf->type == VFRAME_TYPE_IN) { + queue_out(di_buf); + if (vframe_in[di_buf->index]) { + vf_put( + vframe_in[di_buf->index], + VFM_NAME); + vf_notify_provider(VFM_NAME, + VFRAME_EVENT_RECEIVER_PUT, + NULL); +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: vf_put(%d) %x\n", __func__, + di_pre_stru.recycle_seq, + vframe_in[di_buf->index]); +#endif + vframe_in[di_buf->index] = NULL; + } + di_buf->invert_top_bot_flag = 0; + queue_in(di_buf, QUEUE_IN_FREE); + di_pre_stru.recycle_seq++; + ret |= 1; + } else { + queue_out(di_buf); + di_buf->invert_top_bot_flag = 0; + queue_in(di_buf, QUEUE_LOCAL_FREE); + if (di_buf->di_wr_linked_buf) { + queue_in( + di_buf->di_wr_linked_buf, + QUEUE_LOCAL_FREE); +#ifdef DI_BUFFER_DEBUG + di_print( + "%s: linked %s[%d]=>recycle_list\n", + __func__, + vframe_type_name[ + di_buf->di_wr_linked_buf->type], + di_buf->di_wr_linked_buf->index + ); +#endif + di_buf->di_wr_linked_buf = NULL; + } + ret |= 2; + } +#ifdef DI_BUFFER_DEBUG + di_print("%s: recycle %s[%d]\n", __func__, + vframe_type_name[di_buf->type], di_buf->index); +#endif + } + } + return ret; +} + +#ifdef DET3D +static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf) +{ + struct vframe_view_s *left_eye, *right_eye; + + left_eye = &vf->left_eye; + right_eye = &vf->right_eye; + + switch (trans_fmt) { + case TVIN_TFMT_3D_DET_LR: + case TVIN_TFMT_3D_LRH_OLOR: + left_eye->start_x = 0; + left_eye->start_y = 0; + left_eye->width = vf->width >> 1; + left_eye->height = vf->height; + right_eye->start_x = vf->width >> 1; + right_eye->start_y = 0; + right_eye->width = vf->width >> 1; + right_eye->height = vf->height; + break; + case TVIN_TFMT_3D_DET_TB: + case TVIN_TFMT_3D_TB: + left_eye->start_x = 0; + left_eye->start_y = 0; + left_eye->width = vf->width; + left_eye->height = vf->height >> 1; + right_eye->start_x = 0; + right_eye->start_y = vf->height >> 1; + right_eye->width = vf->width; + right_eye->height = vf->height >> 1; + break; + case TVIN_TFMT_3D_DET_INTERLACE: + left_eye->start_x = 0; + left_eye->start_y = 0; + left_eye->width = vf->width; + left_eye->height = vf->height >> 1; + right_eye->start_x = 0; + right_eye->start_y = 0; + right_eye->width = vf->width; + right_eye->height = vf->height >> 1; + break; + case TVIN_TFMT_3D_DET_CHESSBOARD: +/*** + * LRLRLR LRLRLR + * LRLRLR or RLRLRL + * LRLRLR LRLRLR + * LRLRLR RLRLRL + */ + break; + default: /* 2D */ + left_eye->start_x = 0; + left_eye->start_y = 0; + left_eye->width = 0; + left_eye->height = 0; + right_eye->start_x = 0; + right_eye->start_y = 0; + right_eye->width = 0; + right_eye->height = 0; + break; + } +} + +/* + * static int get_3d_info(struct vframe_s *vf) + * { + * int ret = 0; + * + * vf->trans_fmt = det3d_fmt_detect(); + * pr_dbg("[det3d..]new 3d fmt: %d\n", vf->trans_fmt); + * + * vdin_set_view(vf->trans_fmt, vf); + * + * return ret; + * } + */ +static unsigned int det3d_frame_cnt = 50; +module_param_named(det3d_frame_cnt, det3d_frame_cnt, uint, 0644); +static void det3d_irq(void) +{ + unsigned int data32 = 0, likely_val = 0; + unsigned long frame_sum = 0; + + if (!det3d_en) + return; + + data32 = det3d_fmt_detect(); + switch (data32) { + case TVIN_TFMT_3D_DET_LR: + case TVIN_TFMT_3D_LRH_OLOR: + di_pre_stru.det_lr++; + break; + case TVIN_TFMT_3D_DET_TB: + case TVIN_TFMT_3D_TB: + di_pre_stru.det_tp++; + break; + case TVIN_TFMT_3D_DET_INTERLACE: + di_pre_stru.det_la++; + break; + default: + di_pre_stru.det_null++; + break; + } + + if (det3d_mode != data32) { + det3d_mode = data32; + di_print("[det3d..]new 3d fmt: %d\n", det3d_mode); + } + if (frame_count > 20) { + frame_sum = di_pre_stru.det_lr + di_pre_stru.det_tp + + di_pre_stru.det_la + + di_pre_stru.det_null; + if ((frame_count%det3d_frame_cnt) || (frame_sum > UINT_MAX)) + return; + likely_val = max3(di_pre_stru.det_lr, + di_pre_stru.det_tp, + di_pre_stru.det_la); + if (di_pre_stru.det_null >= likely_val) + det3d_mode = 0; + else if (likely_val == di_pre_stru.det_lr) + det3d_mode = TVIN_TFMT_3D_LRH_OLOR; + else if (likely_val == di_pre_stru.det_tp) + det3d_mode = TVIN_TFMT_3D_TB; + else + det3d_mode = TVIN_TFMT_3D_DET_INTERLACE; + di_pre_stru.det3d_trans_fmt = det3d_mode; + } else { + di_pre_stru.det3d_trans_fmt = 0; + } +} +#endif + +static bool calc_mcinfo_en = 1; +module_param(calc_mcinfo_en, bool, 0664); +MODULE_PARM_DESC(calc_mcinfo_en, "/n get mcinfo for post /n"); + +static unsigned int colcfd_thr = 128; +module_param(colcfd_thr, uint, 0664); +MODULE_PARM_DESC(colcfd_thr, "/n threshold for cfd/n"); + +unsigned int ro_mcdi_col_cfd[26]; +static void get_mcinfo_from_reg_in_irq(void) +{ + unsigned int i = 0, ncolcrefsum = 0, blkcount = 0, *reg = NULL; + +/*get info for current field process by post*/ + di_pre_stru.di_wr_buf->curr_field_mcinfo.highvertfrqflg = + (Rd(MCDI_RO_HIGH_VERT_FRQ_FLG) & 0x1); +/* post:MCDI_MC_REL_GAIN_OFFST_0 */ + di_pre_stru.di_wr_buf->curr_field_mcinfo.motionparadoxflg = + (Rd(MCDI_RO_MOTION_PARADOX_FLG) & 0x1); +/* post:MCDI_MC_REL_GAIN_OFFST_0 */ + reg = di_pre_stru.di_wr_buf->curr_field_mcinfo.regs; + for (i = 0; i < 26; i++) { + ro_mcdi_col_cfd[i] = Rd(0x2fb0 + i); + di_pre_stru.di_wr_buf->curr_field_mcinfo.regs[i] = 0; + if (!calc_mcinfo_en) + *(reg + i) = ro_mcdi_col_cfd[i]; + } + if (calc_mcinfo_en) { + blkcount = (di_pre_stru.cur_width + 4) / 5; + for (i = 0; i < blkcount; i++) { + ncolcrefsum += + ((ro_mcdi_col_cfd[i / 32] >> (i % 32)) & 0x1); + if ( + ((ncolcrefsum + (blkcount >> 1)) << 8) / + blkcount > colcfd_thr) + for (i = 0; i < blkcount; i++) + *(reg + i / 32) += (1 << (i % 32)); + } + } +} +static void set_post_mcinfo(struct mcinfo_pre_s *curr_field_mcinfo) +{ + unsigned int i = 0; + + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_REL_GAIN_OFFST_0, + curr_field_mcinfo->highvertfrqflg, 24, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_REL_GAIN_OFFST_0, + curr_field_mcinfo->motionparadoxflg, 25, 1); + for (i = 0; i < 26; i++) + DI_VSYNC_WR_MPEG_REG(0x2f78 + i, curr_field_mcinfo->regs[i]); +} + +static irqreturn_t de_irq(int irq, void *dev_instance) +{ +#ifndef CHECK_DI_DONE + unsigned int data32 = Rd(DI_INTR_CTRL); + unsigned int mask32 = (data32 >> 16) & 0x1ff; + int flag = 0; + + if (di_pre_stru.pre_de_busy) { + /* only one inetrrupr mask should be enable */ + if ((data32 & 2) && !(mask32 & 2)) { + di_print("== MTNWR ==\n"); + flag = 1; + } else if ((data32 & 1) && !(mask32 & 1)) { + di_print("== NRWR ==\n"); + flag = 1; + } else { + di_print("== DI IRQ 0x%x ==\n", data32); + flag = 0; + } + } + +#endif + +#ifdef DET3D + if (det3d_en) { + if ((data32 & 0x100) && !(mask32 & 0x100) && flag) { + DI_Wr(DI_INTR_CTRL, data32); + det3d_irq(); + } else { + goto end; + } + } else { + DI_Wr(DI_INTR_CTRL, data32); + } +#else + DI_Wr(DI_INTR_CTRL, data32); +#endif + if ((post_wr_en && post_wr_surpport) && (data32&0x4)) { + di_post_stru.de_post_process_done = 1; + di_post_stru.post_de_busy = 0; + if (!(data32 & 0x2)) { + DI_Wr(DI_INTR_CTRL, data32); + goto end; + } + } + if (pre_process_time_force) + return IRQ_HANDLED; + + if (di_pre_stru.pre_de_busy == 0) { + di_print("%s: wrong enter %x\n", __func__, Rd(DI_INTR_CTRL)); + return IRQ_HANDLED; + } + + if (flag) { + if (mcpre_en) + get_mcinfo_from_reg_in_irq(); +#ifdef NEW_DI_V4 + if (dnr_en) + run_dnr_in_irq( + di_pre_stru.di_nrwr_mif.end_x + 1, + di_pre_stru.di_nrwr_mif.end_y + 1); + else + if ((Rd(DNR_CTRL) != 0) && dnr_reg_update) + DI_Wr(DNR_CTRL, 0); +#endif + /* disable mif */ + enable_di_pre_mif(0); + di_pre_stru.pre_de_process_done = 1; + di_pre_stru.pre_de_busy = 0; + +end: + if (init_flag && mem_flag) + /* pr_dbg("%s:up di sema\n", __func__); */ + trigger_pre_di_process(TRIGGER_PRE_BY_DE_IRQ); + } + + di_print("DI:buf[%d] irq end.\n", di_pre_stru.di_inp_buf->seq); + + return IRQ_HANDLED; +} + +/* + * di post process + */ +static void inc_post_ref_count(struct di_buf_s *di_buf) +{ +/* int post_blend_mode; */ + + if (di_buf == NULL) { + pr_dbg("%s: Error\n", __func__); + if (recovery_flag == 0) + recovery_log_reason = 13; + + recovery_flag++; + } + + if (di_buf->di_buf_dup_p[1]) + di_buf->di_buf_dup_p[1]->post_ref_count++; + + if (di_buf->di_buf_dup_p[0]) + di_buf->di_buf_dup_p[0]->post_ref_count++; + + if (di_buf->di_buf_dup_p[2]) + di_buf->di_buf_dup_p[2]->post_ref_count++; +} + +static void dec_post_ref_count(struct di_buf_s *di_buf) +{ + if (di_buf == NULL) { + pr_dbg("%s: Error\n", __func__); + if (recovery_flag == 0) + recovery_log_reason = 14; + + recovery_flag++; + } + if (di_buf->pulldown_mode == PULL_DOWN_BUF1) + return; + if (di_buf->di_buf_dup_p[1]) + di_buf->di_buf_dup_p[1]->post_ref_count--; + + if (di_buf->di_buf_dup_p[0] && + di_buf->di_buf_dup_p[0]->post_proc_flag != -2) + di_buf->di_buf_dup_p[0]->post_ref_count--; + + if (di_buf->di_buf_dup_p[2]) + di_buf->di_buf_dup_p[2]->post_ref_count--; +} + +static void vscale_skip_disable_post(struct di_buf_s *di_buf, vframe_t *disp_vf) +{ + struct di_buf_s *di_buf_i = NULL; + int canvas_height = di_buf->di_buf[0]->canvas_height; + + if (di_vscale_skip_enable & 0x2) {/* drop the bottom field */ + if ((di_buf->di_buf_dup_p[0]) && (di_buf->di_buf_dup_p[1])) + di_buf_i = + (di_buf->di_buf_dup_p[1]->vframe->type & + VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_TOP ? di_buf->di_buf_dup_p[1] + : di_buf->di_buf_dup_p[0]; + else + di_buf_i = di_buf->di_buf[0]; + } else { + if ((di_buf->di_buf[0]->post_proc_flag > 0) + && (di_buf->di_buf_dup_p[1])) + di_buf_i = di_buf->di_buf_dup_p[1]; + else + di_buf_i = di_buf->di_buf[0]; + } + disp_vf->type = di_buf_i->vframe->type; + /* pr_dbg("%s (%x %x) (%x %x)\n", __func__, + * disp_vf, disp_vf->type, di_buf_i->vframe, + * di_buf_i->vframe->type); + */ + disp_vf->width = di_buf_i->vframe->width; + disp_vf->height = di_buf_i->vframe->height; + disp_vf->duration = di_buf_i->vframe->duration; + disp_vf->pts = di_buf_i->vframe->pts; + disp_vf->flag = di_buf_i->vframe->flag; + disp_vf->canvas0Addr = di_post_idx[di_post_stru.canvas_id][0]; + disp_vf->canvas1Addr = di_post_idx[di_post_stru.canvas_id][0]; + canvas_config( + di_post_idx[di_post_stru.canvas_id][0], + di_buf_i->nr_adr, di_buf_i->canvas_width[NR_CANVAS], + canvas_height, 0, 0); + disable_post_deinterlace_2(); + di_post_stru.vscale_skip_flag = true; +} +static void process_vscale_skip(struct di_buf_s *di_buf, vframe_t *disp_vf) +{ + int ret = 0, vpp_3d_mode = 0; + if ((di_buf->di_buf[0] != NULL) && (di_vscale_skip_enable & 0x5) && + (di_buf->process_fun_index != PROCESS_FUN_NULL)) { + ret = get_current_vscale_skip_count(disp_vf); + di_vscale_skip_count = (ret & 0xff); + vpp_3d_mode = ((ret >> 8) & 0xff); + if (((di_vscale_skip_count > 0) && + (di_vscale_skip_enable & 0x5)) + || (di_vscale_skip_enable >> 16) + ) { + if ((di_vscale_skip_enable & 0x4) && !vpp_3d_mode) { + if (di_buf->di_buf_dup_p[1] && + di_buf->pulldown_mode != PULL_DOWN_BUF1) + di_buf->pulldown_mode = PULL_DOWN_EI; + } else { + vscale_skip_disable_post(di_buf, disp_vf); + } + } + } +} + +static int de_post_disable_fun(void *arg, vframe_t *disp_vf) +{ + struct di_buf_s *di_buf = (struct di_buf_s *)arg; + + di_post_stru.vscale_skip_flag = false; + di_post_stru.toggle_flag = true; + + process_vscale_skip(di_buf, disp_vf); +/* for atv static image flickering */ + if (di_buf->process_fun_index == PROCESS_FUN_NULL) + disable_post_deinterlace_2(); + + return 1; +/* called for new_format_flag, make + * video set video_property_changed + */ +} + +static int do_nothing_fun(void *arg, vframe_t *disp_vf) +{ + struct di_buf_s *di_buf = (struct di_buf_s *)arg; + + di_post_stru.vscale_skip_flag = false; + di_post_stru.toggle_flag = true; + + process_vscale_skip(di_buf, disp_vf); + + if (di_buf->process_fun_index == PROCESS_FUN_NULL) { + if (Rd(DI_IF1_GEN_REG) & 0x1 || Rd(DI_POST_CTRL) & 0xf) + disable_post_deinterlace_2(); + /*if(di_buf->pulldown_mode == PULL_DOWN_EI && Rd(DI_IF1_GEN_REG)&0x1) + * DI_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, 0x3 << 30); + */ + } + return 0; +} + +static int do_pre_only_fun(void *arg, vframe_t *disp_vf) +{ + di_post_stru.vscale_skip_flag = false; + di_post_stru.toggle_flag = true; + +#ifdef DI_USE_FIXED_CANVAS_IDX + if (arg) { + struct di_buf_s *di_buf = (struct di_buf_s *)arg; + vframe_t *vf = di_buf->vframe; + int width, canvas_height; + + if ((vf == NULL) || (di_buf->di_buf[0] == NULL)) { + di_print("error:%s,NULL point!!\n", __func__); + return 0; + } + width = di_buf->di_buf[0]->canvas_width[NR_CANVAS]; + /* linked two interlace buffer should double height*/ + if (di_buf->di_buf[0]->di_wr_linked_buf) + canvas_height = + (di_buf->di_buf[0]->canvas_height << 1); + else + canvas_height = + di_buf->di_buf[0]->canvas_height; +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + if ((is_vsync_rdma_enable() && + ((force_update_post_reg & 0x40) == 0)) || + (force_update_post_reg & 0x20)) { + di_post_stru.canvas_id = di_post_stru.next_canvas_id; + } else { + di_post_stru.canvas_id = 0; + di_post_stru.next_canvas_id = 1; + } +#endif + + canvas_config( + di_post_idx[di_post_stru.canvas_id][0], + di_buf->di_buf[0]->nr_adr, + di_buf->di_buf[0]->canvas_width[NR_CANVAS], + canvas_height, 0, 0); + + vf->canvas0Addr = + di_post_idx[di_post_stru.canvas_id][0]; + vf->canvas1Addr = + di_post_idx[di_post_stru.canvas_id][0]; +#ifdef DET3D + if (di_pre_stru.vframe_interleave_flag && di_buf->di_buf[1]) { + canvas_config( + di_post_idx[di_post_stru.canvas_id][1], + di_buf->di_buf[1]->nr_adr, + di_buf->di_buf[1]->canvas_width[NR_CANVAS], + canvas_height, 0, 0); + vf->canvas1Addr = + di_post_idx[di_post_stru.canvas_id][1]; + vf->duration <<= 1; + } +#endif + di_post_stru.next_canvas_id = di_post_stru.canvas_id ? 0 : 1; + + if (di_buf->process_fun_index == PROCESS_FUN_NULL) { + if (Rd(DI_IF1_GEN_REG) & 0x1 || Rd(DI_POST_CTRL) & 0xf) + disable_post_deinterlace_2(); + } + + } +#endif + + return 0; +} + +static void config_fftffb_mode(struct di_buf_s *di_buf, + unsigned int *post_field_type, char fftffb_mode) +{ + unsigned char tmp_canvas_idx = 0; + + switch (fftffb_mode) { + case 1: + *post_field_type = + (di_buf->di_buf_dup_p[0]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + di_post_stru.di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + di_post_stru.di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + di_post_stru.di_buf2_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[2]->nr_canvas_idx; + di_post_stru.di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[1]->mtn_canvas_idx; + break; + case 2: + *post_field_type = + (di_buf->di_buf_dup_p[2]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + di_post_stru.di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[2]->nr_canvas_idx; + di_post_stru.di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + di_post_stru.di_buf2_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + di_post_stru.di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[1]->mtn_canvas_idx; + break; + default: + *post_field_type = + (di_buf->di_buf_dup_p[1]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + di_post_stru.di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + di_post_stru.di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + di_post_stru.di_buf2_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[2]->nr_canvas_idx; + di_post_stru.di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mtn_canvas_idx; + break; + } + if (is_meson_txl_cpu() && overturn) { + /* swap if1&if2 mean negation of mv */ + tmp_canvas_idx = di_post_stru.di_buf1_mif.canvas0_addr0; + di_post_stru.di_buf1_mif.canvas0_addr0 = + di_post_stru.di_buf2_mif.canvas0_addr0; + di_post_stru.di_buf2_mif.canvas0_addr0 = tmp_canvas_idx; + } + +} + +static void get_vscale_skip_count(unsigned int par) +{ + di_vscale_skip_count_real = (par >> 24) & 0xff; +} + +#define get_vpp_reg_update_flag(par) ((par >> 16) & 0x1) + +static unsigned int pldn_dly = 1; +static unsigned int tbbtff_dly; + +static unsigned int pldn_wnd_flsh = 1; +module_param(pldn_wnd_flsh, uint, 0644); +MODULE_PARM_DESC(pldn_wnd_flsh, "/n reflesh the window./n"); + +static unsigned int pldn_pst_set; +module_param(pldn_pst_set, uint, 0644); +MODULE_PARM_DESC(pldn_pst_set, "/n pulldown post setting./n"); + +static unsigned int post_blend; +module_param(post_blend, uint, 0664); +MODULE_PARM_DESC(post_blend, "/n show blend mode/n"); +static unsigned int post_ei; +module_param(post_ei, uint, 0664); +MODULE_PARM_DESC(post_ei, "/n show blend mode/n"); +static int +de_post_process(void *arg, unsigned int zoom_start_x_lines, + unsigned int zoom_end_x_lines, unsigned int zoom_start_y_lines, + unsigned int zoom_end_y_lines, vframe_t *disp_vf) +{ + struct di_buf_s *di_buf = (struct di_buf_s *)arg; + struct di_buf_s *di_pldn_buf = di_buf->di_buf_dup_p[pldn_dly]; + unsigned int di_width, di_height, di_start_x, di_end_x; + unsigned int di_start_y, di_end_y, hold_line = post_hold_line; + unsigned int post_blend_en = 0, post_blend_mode = 0, + blend_mtn_en = 0, ei_en = 0, post_field_num = 0; + int di_vpp_en, di_ddr_en; + + if ((di_get_power_control(1) == 0) || di_post_stru.vscale_skip_flag) + return 0; + if (is_in_queue(di_buf, QUEUE_POST_FREE)) { + pr_info("%s post_buf[%d] is in post free list.\n", + __func__, di_buf->index); + return 0; + } + get_vscale_skip_count(zoom_start_x_lines); + + if ((!di_post_stru.toggle_flag) && + ((force_update_post_reg & 0x10) == 0)) + return 0; + + if ((di_buf == NULL) || (di_buf->di_buf_dup_p[0] == NULL)) + return 0; + + if (di_post_stru.toggle_flag && di_buf->di_buf_dup_p[1]) + top_bot_config(di_buf->di_buf_dup_p[1]); + + di_post_stru.toggle_flag = false; + + di_post_stru.cur_disp_index = di_buf->index; + + if ((di_post_stru.post_process_fun_index != 1) || + ((force_update_post_reg & 0xf) != 0)) { + force_update_post_reg &= ~0x1; + di_post_stru.post_process_fun_index = 1; + di_post_stru.update_post_reg_flag = update_post_reg_count; + } + + if (get_vpp_reg_update_flag(zoom_start_x_lines)) + di_post_stru.update_post_reg_flag = update_post_reg_count; +/* pr_dbg("%s set update_post_reg_flag to %d\n", __func__, + * di_post_stru.update_post_reg_flag); + */ + + zoom_start_x_lines = zoom_start_x_lines & 0xffff; + zoom_end_x_lines = zoom_end_x_lines & 0xffff; + zoom_start_y_lines = zoom_start_y_lines & 0xffff; + zoom_end_y_lines = zoom_end_y_lines & 0xffff; + + if (((init_flag == 0) || (mem_flag == 0)) && + (new_keep_last_frame_enable == 0)) + return 0; + + di_start_x = zoom_start_x_lines; + di_end_x = zoom_end_x_lines; + di_width = di_end_x - di_start_x + 1; + di_start_y = zoom_start_y_lines; + di_end_y = zoom_end_y_lines; + di_height = di_end_y - di_start_y + 1; + di_height = di_height / (di_vscale_skip_count_real + 1); + /* make sure the height is even number */ + if (di_height%2) + di_height++; +/* pr_dbg("height = (%d %d %d %d %d)\n", + * di_buf->vframe->height, zoom_start_x_lines, zoom_end_x_lines, + * zoom_start_y_lines, zoom_end_y_lines); + */ + + if (Rd(DI_POST_SIZE) != ((di_width - 1) | ((di_height - 1) << 16)) || + di_post_stru.buf_type != di_buf->di_buf_dup_p[0]->type || + (di_post_stru.di_buf0_mif.luma_x_start0 != di_start_x) || + (di_post_stru.di_buf0_mif.luma_y_start0 != di_start_y / 2)) { + di_post_stru.buf_type = di_buf->di_buf_dup_p[0]->type; + + initial_di_post_2(di_width, di_height, hold_line); + + if ((di_buf->di_buf_dup_p[0]->vframe == NULL) || + (di_buf->vframe == NULL)) + return 0; + /* bit mode config */ + if (di_buf->vframe->bitdepth & BITDEPTH_Y10) { + if (di_buf->vframe->type & VIDTYPE_VIU_444) { + di_post_stru.di_buf0_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:2; + di_post_stru.di_buf1_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:2; + di_post_stru.di_buf2_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:2; + } else { + di_post_stru.di_buf0_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:1; + di_post_stru.di_buf1_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:1; + di_post_stru.di_buf2_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE)?3:1; + } + } else { + di_post_stru.di_buf0_mif.bit_mode = 0; + di_post_stru.di_buf1_mif.bit_mode = 0; + di_post_stru.di_buf2_mif.bit_mode = 0; + } + if (di_buf->vframe->type & VIDTYPE_VIU_444) { + di_post_stru.di_buf0_mif.video_mode = 1; + di_post_stru.di_buf1_mif.video_mode = 1; + di_post_stru.di_buf2_mif.video_mode = 1; + } else { + di_post_stru.di_buf0_mif.video_mode = 0; + di_post_stru.di_buf1_mif.video_mode = 0; + di_post_stru.di_buf2_mif.video_mode = 0; + } + if (di_post_stru.buf_type == VFRAME_TYPE_IN && + !(di_buf->di_buf_dup_p[0]->vframe->type & + VIDTYPE_VIU_FIELD)) { + if (di_buf->vframe->type & VIDTYPE_VIU_NV21) { + di_post_stru.di_buf0_mif.set_separate_en = 1; + di_post_stru.di_buf1_mif.set_separate_en = 1; + di_post_stru.di_buf2_mif.set_separate_en = 1; + } else { + di_post_stru.di_buf0_mif.set_separate_en = 0; + di_post_stru.di_buf1_mif.set_separate_en = 0; + di_post_stru.di_buf2_mif.set_separate_en = 0; + } + di_post_stru.di_buf0_mif.luma_y_start0 = di_start_y; + di_post_stru.di_buf0_mif.luma_y_end0 = di_end_y; + } else { /* from vdin or local vframe process by di pre */ + di_post_stru.di_buf0_mif.set_separate_en = 0; + di_post_stru.di_buf0_mif.luma_y_start0 = + di_start_y >> 1; + di_post_stru.di_buf0_mif.luma_y_end0 = di_end_y >> 1; + di_post_stru.di_buf1_mif.set_separate_en = 0; + di_post_stru.di_buf1_mif.luma_y_start0 = + di_start_y >> 1; + di_post_stru.di_buf1_mif.luma_y_end0 = di_end_y >> 1; + di_post_stru.di_buf2_mif.set_separate_en = 0; + di_post_stru.di_buf2_mif.luma_y_end0 = di_end_y >> 1; + di_post_stru.di_buf2_mif.luma_y_start0 = + di_start_y >> 1; + } + di_post_stru.di_buf0_mif.luma_x_start0 = di_start_x; + di_post_stru.di_buf0_mif.luma_x_end0 = di_end_x; + di_post_stru.di_buf1_mif.luma_x_start0 = di_start_x; + di_post_stru.di_buf1_mif.luma_x_end0 = di_end_x; + di_post_stru.di_buf2_mif.luma_x_start0 = di_start_x; + di_post_stru.di_buf2_mif.luma_x_end0 = di_end_x; + + if ((post_wr_en && post_wr_surpport)) { + di_post_stru.di_diwr_mif.start_x = di_start_x; + di_post_stru.di_diwr_mif.end_x = di_end_x; + di_post_stru.di_diwr_mif.start_y = di_start_y; + di_post_stru.di_diwr_mif.end_y = di_end_y; + } + + di_post_stru.di_mtnprd_mif.start_x = di_start_x; + di_post_stru.di_mtnprd_mif.end_x = di_end_x; + di_post_stru.di_mtnprd_mif.start_y = di_start_y >> 1; + di_post_stru.di_mtnprd_mif.end_y = di_end_y >> 1; + if (mcpre_en) { + di_post_stru.di_mcvecrd_mif.start_x = di_start_x / 5; + di_post_stru.di_mcvecrd_mif.vecrd_offset = + ((di_start_x % 5) ? (5 - di_start_x % 5) : 0); + di_post_stru.di_mcvecrd_mif.start_y = + (di_start_y >> 1); + di_post_stru.di_mcvecrd_mif.size_x = + (di_end_x + 1 + 4) / 5 - 1 - di_start_x / 5; + di_post_stru.di_mcvecrd_mif.size_y = + (di_height >> 1) - 1; + } + di_post_stru.update_post_reg_flag = update_post_reg_count; + /* if height decrease, mtn will not enough */ + if (di_buf->pulldown_mode != PULL_DOWN_BUF1) + di_buf->pulldown_mode = PULL_DOWN_EI; + } + +#ifdef DI_USE_FIXED_CANVAS_IDX +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + if ((is_vsync_rdma_enable() && + ((force_update_post_reg & 0x40) == 0)) || + (force_update_post_reg & 0x20)) { + di_post_stru.canvas_id = di_post_stru.next_canvas_id; + } else { + di_post_stru.canvas_id = 0; + di_post_stru.next_canvas_id = 1; + } +#endif + post_blend = di_buf->pulldown_mode; + switch (di_buf->pulldown_mode) { + case PULL_DOWN_BLEND_0: + case PULL_DOWN_NORMAL: + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[di_post_stru.canvas_id][0], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[2], -1, + di_post_idx[di_post_stru.canvas_id][2]); + config_canvas_idx( + di_buf->di_buf_dup_p[0], + di_post_idx[di_post_stru.canvas_id][1], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[2], + di_post_idx[di_post_stru.canvas_id][3], -1); + if (mcpre_en) + config_mcvec_canvas_idx( + di_buf->di_buf_dup_p[2], + di_post_idx[di_post_stru.canvas_id][4]); + + /* for post_wr_en */ + if ((post_wr_en && post_wr_surpport) && !mcpre_en) + config_canvas_idx( + di_buf, di_post_idx[di_post_stru.canvas_id][4], -1); + break; + case PULL_DOWN_BLEND_2: + config_canvas_idx( + di_buf->di_buf_dup_p[0], + di_post_idx[di_post_stru.canvas_id][3], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[di_post_stru.canvas_id][0], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[2], -1, + di_post_idx[di_post_stru.canvas_id][2]); + config_canvas_idx( + di_buf->di_buf_dup_p[2], + di_post_idx[di_post_stru.canvas_id][1], -1); + if (mcpre_en) + config_mcvec_canvas_idx( + di_buf->di_buf_dup_p[2], + di_post_idx[di_post_stru.canvas_id][4]); + if ((post_wr_en && post_wr_surpport) && !mcpre_en) + config_canvas_idx( + di_buf, di_post_idx[di_post_stru.canvas_id][4], -1); + break; + case PULL_DOWN_MTN: + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[di_post_stru.canvas_id][0], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[2], -1, + di_post_idx[di_post_stru.canvas_id][2]); + config_canvas_idx( + di_buf->di_buf_dup_p[0], + di_post_idx[di_post_stru.canvas_id][1], -1); + if ((post_wr_en && post_wr_surpport)) + config_canvas_idx( +di_buf, di_post_idx[di_post_stru.canvas_id][4], -1); + break; + case PULL_DOWN_BUF1:/* wave with buf1 */ + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[di_post_stru.canvas_id][0], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[1], -1, + di_post_idx[di_post_stru.canvas_id][2]); + config_canvas_idx( + di_buf->di_buf_dup_p[0], + di_post_idx[di_post_stru.canvas_id][1], -1); + if ((post_wr_en && post_wr_surpport)) + config_canvas_idx( +di_buf, di_post_idx[di_post_stru.canvas_id][4], -1); + break; + case PULL_DOWN_EI: + if (di_buf->di_buf_dup_p[1]) + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[di_post_stru.canvas_id][0], -1); + if ((post_wr_en && post_wr_surpport)) + config_canvas_idx( +di_buf, di_post_idx[di_post_stru.canvas_id][4], -1); + break; + default: + break; + } + di_post_stru.next_canvas_id = di_post_stru.canvas_id ? 0 : 1; +#endif + if (di_buf->di_buf_dup_p[1] == NULL) + return 0; + if ((di_buf->di_buf_dup_p[1]->vframe == NULL) || + di_buf->di_buf_dup_p[0]->vframe == NULL) + return 0; + switch (di_buf->pulldown_mode) { + case PULL_DOWN_BLEND_0: + case PULL_DOWN_NORMAL: + config_fftffb_mode(di_buf, &post_field_num, + (di_buf->di_buf_dup_p[tbbtff_dly]->privated&0x3)); + if (mcpre_en) + di_post_stru.di_mcvecrd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mcvec_canvas_idx; + if (di_buf->pulldown_mode == PULL_DOWN_NORMAL) + post_blend_mode = 3; + else + post_blend_mode = 1; + blend_mtn_en = 1; + post_ei = ei_en = 1; + post_blend_en = 1; + break; + case PULL_DOWN_BLEND_2: + post_field_num = + (di_buf->di_buf_dup_p[1]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + di_post_stru.di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + di_post_stru.di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[2]->nr_canvas_idx; + di_post_stru.di_buf2_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + di_post_stru.di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mtn_canvas_idx; + if (mcpre_en) + di_post_stru.di_mcvecrd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mcvec_canvas_idx; + + if ((post_wr_en && post_wr_surpport)) + di_post_stru.di_diwr_mif.canvas_num = + di_post_idx[di_post_stru.canvas_id][4]; + + post_blend_mode = 1; + blend_mtn_en = 1; + post_ei = ei_en = 1; + post_blend_en = 1; + break; + case PULL_DOWN_MTN: + post_field_num = + (di_buf->di_buf_dup_p[1]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + di_post_stru.di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + di_post_stru.di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + di_post_stru.di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mtn_canvas_idx; + if ((post_wr_en && post_wr_surpport)) + di_post_stru.di_diwr_mif.canvas_num = + di_post_idx[di_post_stru.canvas_id][4]; + post_blend_mode = 0; + blend_mtn_en = 1; + post_ei = ei_en = 1; + post_blend_en = 1; + break; + case PULL_DOWN_BUF1: + post_field_num = + (di_buf->di_buf_dup_p[1]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + di_post_stru.di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + di_post_stru.di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[1]->mtn_canvas_idx; + di_post_stru.di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + if ((post_wr_en && post_wr_surpport)) + di_post_stru.di_diwr_mif.canvas_num = + di_post_idx[di_post_stru.canvas_id][4]; + post_blend_mode = 1; + blend_mtn_en = 0; + post_ei = ei_en = 0; + post_blend_en = 0; + break; + case PULL_DOWN_EI: + if (di_buf->di_buf_dup_p[1]) { + di_post_stru.di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + post_field_num = + (di_buf->di_buf_dup_p[1]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + } else { + post_field_num = + (di_buf->di_buf_dup_p[0]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + di_post_stru.di_buf0_mif.src_field_mode + = post_field_num; + } + if ((post_wr_en && post_wr_surpport)) + di_post_stru.di_diwr_mif.canvas_num = + di_post_idx[di_post_stru.canvas_id][4]; + post_blend_mode = 2; + blend_mtn_en = 0; + post_ei = ei_en = 1; + post_blend_en = 0; + break; + default: + break; + } + + if ((post_wr_en && post_wr_surpport)) { + di_vpp_en = 0; + di_ddr_en = 1; + } else { + di_vpp_en = 1; + di_ddr_en = 0; + } + + /* if post size < MIN_POST_WIDTH, force ei */ + if ((di_width < MIN_BLEND_WIDTH) && + (di_buf->pulldown_mode == PULL_DOWN_BLEND_0 || + di_buf->pulldown_mode == PULL_DOWN_BLEND_2 || + di_buf->pulldown_mode == PULL_DOWN_NORMAL + )) { + post_blend_mode = 1; + blend_mtn_en = 0; + post_ei = ei_en = 0; + post_blend_en = 0; + } + + if (mcpre_en) + di_post_stru.di_mcvecrd_mif.blend_mode = post_blend_mode; + + if ((di_post_stru.update_post_reg_flag) && + ((force_update_post_reg & 0x80) == 0)) { + enable_di_post_2( + &di_post_stru.di_buf0_mif, + &di_post_stru.di_buf1_mif, + &di_post_stru.di_buf2_mif, + (di_ddr_en ? + (&di_post_stru.di_diwr_mif):NULL), + &di_post_stru.di_mtnprd_mif, + ei_en, /* ei enable */ + post_blend_en, /* blend enable */ + blend_mtn_en, /* blend mtn enable */ + post_blend_mode, /* blend mode. */ + di_vpp_en, /* di_vpp_en. */ + di_ddr_en, /* di_ddr_en. */ + post_field_num, /* 1 bottom generate top */ + hold_line, + post_urgent + ); + if (mcpre_en) + enable_mc_di_post( + &di_post_stru.di_mcvecrd_mif, post_urgent, + overturn); + else if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + } else { + di_post_switch_buffer( + &di_post_stru.di_buf0_mif, + &di_post_stru.di_buf1_mif, + &di_post_stru.di_buf2_mif, +(di_ddr_en ? (&di_post_stru.di_diwr_mif):NULL), + &di_post_stru.di_mtnprd_mif, + &di_post_stru.di_mcvecrd_mif, + ei_en, /* ei enable */ + post_blend_en, /* blend enable */ + blend_mtn_en, /* blend mtn enable */ + post_blend_mode, /* blend mode. */ + di_vpp_en, /* di_vpp_en. */ + di_ddr_en, /* di_ddr_en. */ + post_field_num, /* 1 bottom generate top */ + hold_line, + post_urgent + ); + } + +#ifdef NEW_DI_V1 + if (di_post_stru.update_post_reg_flag && (!combing_fix_en)) { + di_apply_reg_cfg(1); + last_lev = -1; + } + +#endif + if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) + di_post_read_reverse_irq(overturn); + if (mcpre_en) { + if (di_buf->di_buf_dup_p[2]) + set_post_mcinfo(&di_buf->di_buf_dup_p[2] + ->curr_field_mcinfo); + } else if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + + +/* set pull down region (f(t-1) */ + + if (di_pldn_buf && pulldown_enable && + !di_pre_stru.cur_prog_flag) { + if (pldn_wnd_flsh == 1) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG0_Y, + di_pldn_buf->reg0_s, 17, 12); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG0_Y, + di_pldn_buf->reg0_e, 1, 12); + + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG1_Y, + di_pldn_buf->reg1_s, 17, 12); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG1_Y, + di_pldn_buf->reg1_e, 1, 12); + + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG2_Y, + di_pldn_buf->reg2_s, 17, 12); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG2_Y, + di_pldn_buf->reg2_e, 1, 12); + + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG3_Y, + di_pldn_buf->reg3_s, 17, 12); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG3_Y, + di_pldn_buf->reg3_e, 1, 12); + +/* region0 */ + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + (di_pldn_buf->reg0_e > di_pldn_buf->reg0_s) + ? 1 : 0, 16, 1); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + di_pldn_buf->reg0_bmode, 8, 2); + + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + (di_pldn_buf->reg1_e > di_pldn_buf->reg1_s) + ? 1 : 0, 17, 1); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + di_pldn_buf->reg1_bmode, 10, 2); + + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + (di_pldn_buf->reg2_e > di_pldn_buf->reg2_s) + ? 1 : 0, 18, 1); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + di_pldn_buf->reg2_bmode, 12, 2); + + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + (di_pldn_buf->reg3_e > di_pldn_buf->reg3_s) + ? 1 : 0, 19, 1); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + di_pldn_buf->reg3_bmode, 14, 2); + } else if (pldn_wnd_flsh == 2) { + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_Y, 479); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_Y, 160); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_Y, 320 << 16 | 160); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_Y, 479 << 16 | 320); + RDMA_WR(DI_BLEND_CTRL, 0x81f00019); /* normal */ + } + + if (pldn_pst_set == 1) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 1, 17, 1); +/* weaver */ + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 1, 10, 2); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_Y, 120); + } else if (pldn_pst_set == 2) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 1, 18, 1); +/* bob */ + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 2, 12, 2); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_Y, 120); + } else if (pldn_pst_set == 3) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 1, 19, 1); +/* bob mtn */ + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 0, 14, 2); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_Y, 120); + } else if (pldn_pst_set == 5) { + RDMA_WR(DI_BLEND_CTRL, 0x81f00019); /* normal */ + } + } + + if (di_post_stru.update_post_reg_flag > 0) + di_post_stru.update_post_reg_flag--; + return 0; +} + + +static void post_de_done_buf_config(void) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + struct di_buf_s *di_buf = NULL; + + if (di_post_stru.cur_post_buf == NULL) + return; + + di_lock_irqfiq_save(irq_flag2, fiq_flag); + queue_out(di_post_stru.cur_post_buf); + di_buf = di_post_stru.cur_post_buf; + queue_in(di_post_stru.cur_post_buf, QUEUE_POST_READY); + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + vf_notify_receiver(VFM_NAME, VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + di_post_stru.cur_post_buf = NULL; + +} + +static void di_post_process(void) +{ + struct di_buf_s *di_buf = NULL; + vframe_t *vf_p = NULL; + + + if (!queue_empty(QUEUE_POST_DOING) && !di_post_stru.post_de_busy) { + di_buf = get_di_buf_head(QUEUE_POST_DOING); + if (check_di_buf(di_buf, 20)) + return; + vf_p = di_buf->vframe; + if (di_post_stru.run_early_proc_fun_flag) { + if (vf_p->early_process_fun) + vf_p->early_process_fun( + vf_p->private_data, vf_p); + } + if (di_buf->process_fun_index) + de_post_process( + di_buf, 0, vf_p->width-1, + 0, vf_p->height-1, vf_p); + di_post_stru.post_de_busy = 1; + di_post_stru.cur_post_buf = di_buf; + } +} + +int pd_detect_rst; + +static void recycle_vframe_type_post(struct di_buf_s *di_buf) +{ + int i; + + if (di_buf == NULL) { + pr_dbg("%s:Error\n", __func__); + if (recovery_flag == 0) + recovery_log_reason = 15; + + recovery_flag++; + return; + } + if (di_buf->process_fun_index == PROCESS_FUN_DI) + dec_post_ref_count(di_buf); + + for (i = 0; i < 2; i++) { + if (di_buf->di_buf[i]) + queue_in(di_buf->di_buf[i], QUEUE_RECYCLE); + } + queue_out(di_buf); /* remove it from display_list_head */ + di_buf->invert_top_bot_flag = 0; + queue_in(di_buf, QUEUE_POST_FREE); +} + +#ifdef DI_BUFFER_DEBUG +static void +recycle_vframe_type_post_print(struct di_buf_s *di_buf, + const char *func, + const int line) +{ + int i; + + di_print("%s:%d ", func, line); + for (i = 0; i < 2; i++) { + if (di_buf->di_buf[i]) + di_print("%s[%d]<%d>=>recycle_list; ", + vframe_type_name[di_buf->di_buf[i]->type], + di_buf->di_buf[i]->index, i); + } + di_print("%s[%d] =>post_free_list\n", + vframe_type_name[di_buf->type], di_buf->index); +} +#endif +static int debug_blend_mode = -1; +static unsigned int pldn_dly1 = 1; +static unsigned int pldn_pst_wver = 5; +static void set_pulldown_mode(struct di_buf_s *di_buf) +{ + struct di_buf_s *pre_buf_p = di_buf->di_buf_dup_p[pldn_dly1]; + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB)) { + if (pulldown_enable && !di_pre_stru.cur_prog_flag) { + if (pre_buf_p) { + di_buf->pulldown_mode = + pre_buf_p->pulldown_mode; + } else { + pr_err("DI[%s]: index out of range.\n", + __func__); + } + } else { + di_buf->pulldown_mode = PULL_DOWN_NORMAL; + } + if (pldn_pst_wver != 5) { + if (pldn_pst_wver > 5) + pldn_pst_wver = 5; + di_buf->pulldown_mode = pldn_pst_wver; + } + } +} + +void drop_frame(int check_drop, int throw_flag, struct di_buf_s *di_buf) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + int i = 0, drop_flag = 0; + + di_lock_irqfiq_save(irq_flag2, fiq_flag); + if ((frame_count == 0) && check_drop) + di_post_stru.start_pts = di_buf->vframe->pts; + if ((check_drop && (frame_count < start_frame_drop_count)) + || throw_flag) { + drop_flag = 1; + } else { + if (check_drop && (frame_count == start_frame_drop_count)) { + if ((di_post_stru.start_pts) + && (di_buf->vframe->pts == 0)) + di_buf->vframe->pts = di_post_stru.start_pts; + di_post_stru.start_pts = 0; + } + for (i = 0; i < 3; i++) { + if (di_buf->di_buf_dup_p[i]) { + if (di_buf->di_buf_dup_p[i]->vframe->bitdepth != + di_buf->vframe->bitdepth) { + pr_info("%s buf[%d] not match bit mode\n", + __func__, i); + drop_flag = 1; + break; + } + } + } + } + if (drop_flag) { + queue_in(di_buf, QUEUE_TMP); + recycle_vframe_type_post(di_buf); +#ifdef DI_BUFFER_DEBUG + recycle_vframe_type_post_print( + di_buf, __func__, + __LINE__); +#endif + } else { + if ((post_wr_en && post_wr_surpport)) + queue_in(di_buf, QUEUE_POST_DOING); + else + queue_in(di_buf, QUEUE_POST_READY); + di_print("DI:%s[%d] => post ready %u ms.\n", + vframe_type_name[di_buf->type], di_buf->index, + jiffies_to_msecs(jiffies_64 - di_buf->vframe->ready_jiffies64)); + + + } + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); +} + +static int process_post_vframe(void) +{ +/* + * 1) get buf from post_free_list, config it according to buf + * in pre_ready_list, send it to post_ready_list + * (it will be send to post_free_list in di_vf_put()) + * 2) get buf from pre_ready_list, attach it to buf from post_free_list + * (it will be send to recycle_list in di_vf_put() ) + */ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + int i = 0; + int ret = 0; + int buffer_keep_count = 3; + struct di_buf_s *di_buf = NULL; + struct di_buf_s *ready_di_buf; + struct di_buf_s *p = NULL;/* , *ptmp; */ + int itmp; + int ready_count = list_count(QUEUE_PRE_READY); + bool check_drop = false; + + if (queue_empty(QUEUE_POST_FREE)) + return 0; + + if (ready_count == 0) + return 0; + + ready_di_buf = get_di_buf_head(QUEUE_PRE_READY); + if ((ready_di_buf == NULL) || (ready_di_buf->vframe == NULL)) { + + pr_dbg("%s:Error1\n", __func__); + + if (recovery_flag == 0) + recovery_log_reason = 16; + + recovery_flag++; + return 0; + } + + if ((ready_di_buf->post_proc_flag) && + (ready_count >= buffer_keep_count)) { + i = 0; + queue_for_each_entry(p, ptmp, QUEUE_PRE_READY, list) { + /* if(p->post_proc_flag == 0){ */ + if (p->type == VFRAME_TYPE_IN) { + ready_di_buf->post_proc_flag = -1; + ready_di_buf->new_format_flag = 1; + } + i++; + if (i > 2) + break; + } + } + if (ready_di_buf->post_proc_flag > 0) { + if (ready_count >= buffer_keep_count) { + di_lock_irqfiq_save(irq_flag2, fiq_flag); + di_buf = get_di_buf_head(QUEUE_POST_FREE); + if (check_di_buf(di_buf, 17)) + return 0; + + queue_out(di_buf); + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + + i = 0; + queue_for_each_entry( + p, ptmp, QUEUE_PRE_READY, list) { + di_buf->di_buf_dup_p[i++] = p; + if (i >= buffer_keep_count) + break; + } + if (i < buffer_keep_count) { + + pr_dbg("%s:Error3\n", __func__); + + if (recovery_flag == 0) + recovery_log_reason = 18; + recovery_flag++; + return 0; + } + + memcpy(di_buf->vframe, + di_buf->di_buf_dup_p[1]->vframe, + sizeof(vframe_t)); + di_buf->vframe->private_data = di_buf; + if (di_buf->di_buf_dup_p[1]->post_proc_flag == 3) { + /* dummy, not for display */ + inc_post_ref_count(di_buf); + di_buf->di_buf[0] = di_buf->di_buf_dup_p[0]; + di_buf->di_buf[1] = NULL; + queue_out(di_buf->di_buf[0]); + di_lock_irqfiq_save(irq_flag2, fiq_flag); + queue_in(di_buf, QUEUE_TMP); + recycle_vframe_type_post(di_buf); + + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); +#ifdef DI_BUFFER_DEBUG + di_print("%s : ", __func__); +#endif + } else { + if (di_buf->di_buf_dup_p[1]-> + post_proc_flag == 2){ + di_buf->pulldown_mode + = PULL_DOWN_BLEND_2; + /* blend with di_buf->di_buf_dup_p[2] */ + } else { + set_pulldown_mode(di_buf); + } + di_buf->vframe->type = + VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD; + if ( + di_buf->di_buf_dup_p[1]-> + new_format_flag) { + /* if (di_buf->di_buf_dup_p[1] + * ->post_proc_flag == 2) { + */ + di_buf->vframe-> + early_process_fun + = de_post_disable_fun; + } else { + di_buf->vframe-> + early_process_fun + = do_nothing_fun; + } + + if (di_buf->di_buf_dup_p[1]->type + == VFRAME_TYPE_IN) { + /* next will be bypass */ + di_buf->vframe->type + = VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE + | VIDTYPE_VIU_FIELD; + di_buf->vframe->height >>= 1; + di_buf->vframe->canvas0Addr = + di_buf->di_buf_dup_p[0] + ->nr_canvas_idx; /* top */ + di_buf->vframe->canvas1Addr = + di_buf->di_buf_dup_p[0] + ->nr_canvas_idx; + di_buf->vframe->process_fun = + NULL; + di_buf->process_fun_index = + PROCESS_FUN_NULL; + } else { + /*for debug*/ + if (debug_blend_mode != -1) + di_buf->pulldown_mode = + debug_blend_mode; + + di_buf->vframe->process_fun = +((post_wr_en && post_wr_surpport) ? NULL : de_post_process); + di_buf->process_fun_index = + PROCESS_FUN_DI; + inc_post_ref_count(di_buf); + } + di_buf->di_buf[0] + = di_buf->di_buf_dup_p[0]; + di_buf->di_buf[1] = NULL; + queue_out(di_buf->di_buf[0]); + + drop_frame(true, + (di_buf->di_buf_dup_p[0]->throw_flag) || + (di_buf->di_buf_dup_p[1]->throw_flag) || + (di_buf->di_buf_dup_p[2]->throw_flag), + di_buf); + + frame_count++; +#ifdef DI_BUFFER_DEBUG + di_print("%s : ", __func__); +#endif + if (!(post_wr_en && post_wr_surpport)) + vf_notify_receiver(VFM_NAME, +VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + } + ret = 1; + } + } else { + if (is_progressive(ready_di_buf->vframe) || + ready_di_buf->type == VFRAME_TYPE_IN || + ready_di_buf->post_proc_flag < 0 || + bypass_post_state + ){ + int vframe_process_count = 1; +#ifdef DET3D + int dual_vframe_flag = 0; + + if ((di_pre_stru.vframe_interleave_flag && + ready_di_buf->left_right) || + (bypass_post & 0x100)) { + dual_vframe_flag = 1; + vframe_process_count = 2; + } +#endif + if (skip_top_bot && + (!is_progressive(ready_di_buf->vframe))) + vframe_process_count = 2; + + if (ready_count >= vframe_process_count) { + struct di_buf_s *di_buf_i; + + di_lock_irqfiq_save(irq_flag2, fiq_flag); + di_buf = get_di_buf_head(QUEUE_POST_FREE); + if (check_di_buf(di_buf, 19)) + return 0; + + queue_out(di_buf); + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + + i = 0; + queue_for_each_entry( + p, ptmp, QUEUE_PRE_READY, list){ + di_buf->di_buf_dup_p[i++] = p; + if (i >= vframe_process_count) { + di_buf->di_buf_dup_p[i] = NULL; + di_buf->di_buf_dup_p[i+1] = + NULL; + break; + } + } + if (i < vframe_process_count) { + pr_dbg("%s:Error6\n", __func__); + if (recovery_flag == 0) + recovery_log_reason = 22; + + recovery_flag++; + return 0; + } + + di_buf_i = di_buf->di_buf_dup_p[0]; + if (!is_progressive(ready_di_buf->vframe) + && ((skip_top_bot == 1) + || (skip_top_bot == 2))) { + unsigned int frame_type = + di_buf->di_buf_dup_p[1]-> + vframe->type & VIDTYPE_TYPEMASK; + if (skip_top_bot == 1) { + di_buf_i = (frame_type == + VIDTYPE_INTERLACE_TOP) + ? di_buf->di_buf_dup_p[1] + : di_buf->di_buf_dup_p[0]; + } else if (skip_top_bot == 2) { + di_buf_i = (frame_type == + VIDTYPE_INTERLACE_BOTTOM) + ? di_buf->di_buf_dup_p[1] + : di_buf->di_buf_dup_p[0]; + } + } + + memcpy(di_buf->vframe, + di_buf_i->vframe, + sizeof(vframe_t)); + di_buf->vframe->private_data = di_buf; + + if (ready_di_buf->new_format_flag && + (ready_di_buf->type == VFRAME_TYPE_IN)) { + pr_info("DI:%d disable post.\n", + __LINE__); + di_buf->vframe->early_process_fun + = de_post_disable_fun; + } else { + if (ready_di_buf->type == + VFRAME_TYPE_IN) + di_buf->vframe-> + early_process_fun + = do_nothing_fun; + + else + di_buf->vframe-> + early_process_fun + = do_pre_only_fun; + } + if (ready_di_buf->post_proc_flag == -2) { + di_buf->vframe->type + |= VIDTYPE_VIU_FIELD; + di_buf->vframe->type + &= ~(VIDTYPE_TYPEMASK); + di_buf->vframe->process_fun += (post_wr_en && post_wr_surpport)?NULL:de_post_process; + di_buf->process_fun_index + = PROCESS_FUN_DI; + di_buf->pulldown_mode + = PULL_DOWN_EI; + } else { + di_buf->vframe->process_fun = + NULL; + di_buf->process_fun_index = + PROCESS_FUN_NULL; + di_buf->pulldown_mode = + PULL_DOWN_NORMAL; + } + di_buf->di_buf[0] = ready_di_buf; + di_buf->di_buf[1] = NULL; + queue_out(ready_di_buf); + +#ifdef DET3D + if (dual_vframe_flag) { + di_buf->di_buf[1] = + di_buf->di_buf_dup_p[1]; + queue_out(di_buf->di_buf[1]); + } +#endif + if ((check_start_drop_prog && + is_progressive(ready_di_buf->vframe)) + || !is_progressive(ready_di_buf->vframe)) + check_drop = true; + drop_frame(check_drop, + di_buf->di_buf[0]->throw_flag, di_buf); + + frame_count++; +#ifdef DI_BUFFER_DEBUG + di_print( + "%s : ", + __func__); +#endif + ret = 1; + vf_notify_receiver(VFM_NAME, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); + } + } else if (ready_count >= 2) { + /*for progressive input,type + * 1:separate tow fields,type + * 2:bypass post as frame + */ + unsigned char prog_tb_field_proc_type = + (prog_proc_config >> 1) & 0x3; + di_lock_irqfiq_save(irq_flag2, fiq_flag); + di_buf = get_di_buf_head(QUEUE_POST_FREE); + + if (check_di_buf(di_buf, 20)) + return 0; + + queue_out(di_buf); + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + + i = 0; + queue_for_each_entry( + p, ptmp, QUEUE_PRE_READY, list) { + di_buf->di_buf_dup_p[i++] = p; + if (i >= 2) { + di_buf->di_buf_dup_p[i] = NULL; + break; + } + } + if (i < 2) { + pr_dbg("%s:Error6\n", __func__); + + if (recovery_flag == 0) + recovery_log_reason = 21; + + recovery_flag++; + return 0; + } + + memcpy(di_buf->vframe, + di_buf->di_buf_dup_p[0]->vframe, + sizeof(vframe_t)); + di_buf->vframe->private_data = di_buf; + + /*separate one progressive frame + * as two interlace fields + */ + if (prog_tb_field_proc_type == 1) { + /* do weave by di post */ + di_buf->vframe->type = + VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD; + if ( + di_buf->di_buf_dup_p[0]-> + new_format_flag) + di_buf->vframe-> + early_process_fun = + de_post_disable_fun; + else + di_buf->vframe-> + early_process_fun = + do_nothing_fun; + + di_buf->pulldown_mode = PULL_DOWN_BUF1; + di_buf->vframe->process_fun = +(post_wr_en && post_wr_surpport)?NULL:de_post_process; + di_buf->process_fun_index = + PROCESS_FUN_DI; + } else if (prog_tb_field_proc_type == 0) { + /* to do: need change for + * DI_USE_FIXED_CANVAS_IDX + */ + /* do weave by vpp */ + di_buf->vframe->type = + VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE; + if ( + (di_buf->di_buf_dup_p[0]-> + new_format_flag) || + (Rd(DI_IF1_GEN_REG) & 1)) + di_buf->vframe-> + early_process_fun = + de_post_disable_fun; + else + di_buf->vframe-> + early_process_fun = + do_nothing_fun; + di_buf->vframe->process_fun = NULL; + di_buf->process_fun_index = + PROCESS_FUN_NULL; + di_buf->vframe->canvas0Addr = + di_buf->di_buf_dup_p[0]-> + nr_canvas_idx; + di_buf->vframe->canvas1Addr = + di_buf->di_buf_dup_p[1]-> + nr_canvas_idx; + } else { + /* to do: need change for + * DI_USE_FIXED_CANVAS_IDX + */ + di_buf->vframe->type = + VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD; + di_buf->vframe->height >>= 1; + if ( + (di_buf->di_buf_dup_p[0]-> + new_format_flag) || + (Rd(DI_IF1_GEN_REG) & 1)) + di_buf->vframe-> + early_process_fun = + de_post_disable_fun; + else + di_buf->vframe-> + early_process_fun = + do_nothing_fun; + if (prog_tb_field_proc_type == 2) { + di_buf->vframe->canvas0Addr = + di_buf->di_buf_dup_p[0] + ->nr_canvas_idx; +/* top */ + di_buf->vframe->canvas1Addr = + di_buf->di_buf_dup_p[0] + ->nr_canvas_idx; + } else { + di_buf->vframe->canvas0Addr = + di_buf->di_buf_dup_p[1] + ->nr_canvas_idx; /* top */ + di_buf->vframe->canvas1Addr = + di_buf->di_buf_dup_p[1] + ->nr_canvas_idx; + } + } + + di_buf->di_buf[0] = di_buf->di_buf_dup_p[0]; + queue_out(di_buf->di_buf[0]); + /*check if the field is error,then drop*/ + if ( + (di_buf->di_buf_dup_p[0]->vframe->type & + VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_BOTTOM) { + di_buf->di_buf[1] = + di_buf->di_buf_dup_p[1] = NULL; + di_lock_irqfiq_save(irq_flag2, + fiq_flag); + queue_in(di_buf, QUEUE_TMP); + recycle_vframe_type_post(di_buf); + pr_dbg("%s drop field %d.\n", __func__, + di_buf->di_buf_dup_p[0]->seq); + } else { + di_buf->di_buf[1] = + di_buf->di_buf_dup_p[1]; + queue_out(di_buf->di_buf[1]); + + drop_frame(check_start_drop_prog, + (di_buf->di_buf_dup_p[0]->throw_flag) || + (di_buf->di_buf_dup_p[1]->throw_flag), + di_buf); + } + frame_count++; +#ifdef DI_BUFFER_DEBUG + di_print("%s : ", __func__); +#endif + ret = 1; + vf_notify_receiver(VFM_NAME, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); + } + } + +#ifdef DI_BUFFER_DEBUG + if (di_buf) { + di_print("%s[%d](", + vframe_type_name[di_buf->type], di_buf->index); + for (i = 0; i < 2; i++) { + if (di_buf->di_buf[i]) + di_print("%s[%d],", + vframe_type_name[di_buf->di_buf[i]->type], + di_buf->di_buf[i]->index); + } + di_print(")(vframe type %x dur %d)", + di_buf->vframe->type, di_buf->vframe->duration); + if (di_buf->di_buf_dup_p[1] && + (di_buf->di_buf_dup_p[1]->post_proc_flag == 3)) + di_print("=> recycle_list\n"); + else + di_print("=> post_ready_list\n"); + } +#endif + return ret; +} + +/* + * di task + */ +static void di_unreg_process(void) +{ + if (reg_flag) { + field_count = 0; + vf_unreg_provider(&di_vf_prov); + reg_flag = 0; + unreg_cnt++; + if (unreg_cnt > 0x3fffffff) + unreg_cnt = 0; + di_print("########%s\n", __func__); + di_pre_stru.unreg_req_flag_irq = 1; + trigger_pre_di_process(TRIGGER_PRE_BY_UNREG); + } else { + di_pre_stru.force_unreg_req_flag = 0; + di_pre_stru.disable_req_flag = 0; + recovery_flag = 0; + di_pre_stru.unreg_req_flag = 0; + } +} + +static void di_unreg_process_irq(void) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + +#if (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_lock_irqsave(&plist_lock, flags); +#endif + di_lock_irqfiq_save(irq_flag2, fiq_flag); + di_print("%s: di_uninit_buf\n", __func__); + di_uninit_buf(); + init_flag = 0; +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA +/* stop rdma */ + rdma_clear(de_devp->rdma_handle); +#endif + adpative_combing_exit(); + di_set_power_control(0, 0); +#ifndef NEW_DI_V3 + DI_Wr(DI_CLKG_CTRL, 0xff0000); +/* di enable nr clock gate */ +#else + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) + DI_Wr(DI_CLKG_CTRL, 0x80f60000); + else + DI_Wr(DI_CLKG_CTRL, 0xf60000); +/* nr/blend0/ei0/mtn0 clock gate */ +#endif + if (get_blackout_policy()) { + di_set_power_control(1, 0); + DI_Wr(DI_CLKG_CTRL, 0x80000000); + switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_OFF); + } + if ((post_wr_en && post_wr_surpport)) { + diwr_set_power_control(0); + #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + enable_rdma(1); + #endif + } + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + +#if (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_unlock_irqrestore(&plist_lock, flags); +#endif + + di_pre_stru.force_unreg_req_flag = 0; + di_pre_stru.disable_req_flag = 0; + recovery_flag = 0; +#ifdef NEW_DI_V3 + di_pre_stru.cur_prog_flag = 0; +#endif + di_pre_stru.unreg_req_flag = 0; + di_pre_stru.unreg_req_flag_irq = 0; +} + +static void di_reg_process(void) +{ +/*get vout information first time*/ + if (reg_flag == 1) + return; + vf_provider_init(&di_vf_prov, VFM_NAME, &deinterlace_vf_provider, NULL); + vf_reg_provider(&di_vf_prov); + vf_notify_receiver(VFM_NAME, VFRAME_EVENT_PROVIDER_START, NULL); + reg_flag = 1; + reg_cnt++; + if (reg_cnt > 0x3fffffff) + reg_cnt = 0; + di_print("########%s\n", __func__); +} +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA +/* di pre rdma operation */ +static void di_rdma_irq(void *arg) +{ + struct di_dev_s *di_devp = (struct di_dev_s *)arg; + + if (!di_devp || (di_devp->rdma_handle <= 0)) { + pr_err("%s rdma handle %d error.\n", __func__, + di_devp->rdma_handle); + return; + } + if (di_printk_flag) + pr_dbg("%s...%d.\n", __func__, + di_pre_stru.field_count_for_cont); +} + +static struct rdma_op_s di_rdma_op = { + di_rdma_irq, + NULL +}; +#endif +static void di_reg_process_irq(void) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + vframe_t *vframe; + + if ((pre_run_flag != DI_RUN_FLAG_RUN) && + (pre_run_flag != DI_RUN_FLAG_STEP)) + return; + if (pre_run_flag == DI_RUN_FLAG_STEP) + pre_run_flag = DI_RUN_FLAG_STEP_DONE; + + /*di_pre_stru.reg_req_flag = 1;*/ + /*trigger_pre_di_process(TRIGGER_PRE_BY_TIMERC);*/ + + vframe = vf_peek(VFM_NAME); + + if (vframe) { + #ifdef CONFIG_CMA + if ((vframe->width > default_width) || + (vframe->height > (default_height + 8))) + bypass_4K = 1; + else + bypass_4K = 0; + #endif + /* patch for vdin progressive input */ + if (((vframe->type & VIDTYPE_VIU_422) && + ((vframe->type & VIDTYPE_PROGRESSIVE) == 0)) + #ifdef DET3D + || det3d_en + #endif + || (use_2_interlace_buff & 0x2) + ) + use_2_interlace_buff = 1; + else + use_2_interlace_buff = 0; + switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON); + di_set_power_control(0, 1); + di_set_power_control(1, 1); + if ((post_wr_en && post_wr_surpport)) { + diwr_set_power_control(1); + #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + enable_rdma(0); + #endif + } +#ifndef NEW_DI_V3 + DI_Wr(DI_CLKG_CTRL, 0xfeff0000); + /* di enable nr clock gate */ +#else + /* if mcdi enable DI_CLKG_CTRL should be 0xfef60000 */ + DI_Wr(DI_CLKG_CTRL, 0xfef60001); + /* nr/blend0/ei0/mtn0 clock gate */ +#endif + /* add for di Reg re-init */ +#ifdef NEW_DI_TV + di_set_para_by_tvinfo(vframe); +#endif + if (di_printk_flag & 2) + di_printk_flag = 1; + + di_print("%s: vframe come => di_init_buf\n", __func__); + + if (is_progressive(vframe) && (prog_proc_config & 0x10)) { +#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_lock_irqsave(&plist_lock, flags); +#endif + di_lock_irqfiq_save(irq_flag2, fiq_flag); + /* + * 10 bit mode need 1.5 times buffer size of + * 8 bit mode, init the buffer size as 10 bit + * mode size, to make sure can switch bit mode + * smoothly. + */ + di_init_buf(default_width, default_height, 1); + + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + +#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_unlock_irqrestore(&plist_lock, flags); +#endif + } else { +#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_lock_irqsave(&plist_lock, flags); +#endif + di_lock_irqfiq_save(irq_flag2, fiq_flag); + /* + * 10 bit mode need 1.5 times buffer size of + * 8 bit mode, init the buffer size as 10 bit + * mode size, to make sure can switch bit mode + * smoothly. + */ + di_init_buf(default_width, default_height, 0); + + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + +#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_unlock_irqrestore(&plist_lock, flags); +#endif + } + + if (pulldown_enable) { + FlmVOFSftInt(&pd_param); + flm22_sure_num = (vframe->height * 100)/480; + flm22_sure_smnum = (flm22_sure_num * flm22_ratio)/100; + } + + adpative_combing_config(vframe->width, + (vframe->height>>1), + (vframe->source_type), + is_progressive(vframe), + vframe->sig_fmt); + if (is_meson_txl_cpu()) { + combing_pd22_window_config(vframe->width, + (vframe->height>>1)); + tbff_init(); + } + init_flag = 1; + di_pre_stru.reg_req_flag_irq = 1; + } +} + +static void di_process(void) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + + di_process_cnt++; + + if (init_flag && mem_flag && (recovery_flag == 0) && + (dump_state_flag == 0)) { +#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_lock_irqsave(&plist_lock, flags); +#endif + if (di_pre_stru.pre_de_busy == 0) { + if (di_pre_stru.pre_de_process_done) { +#if 0/*def CHECK_DI_DONE*/ + /* also for NEW_DI ? 7/15/2013 */ + unsigned int data32 = Rd(DI_INTR_CTRL); + /*DI_INTR_CTRL[bit 0], NRWR_done, set by + * hardware when NRWR is done,clear by write 1 + * by code;[bit 1] + * MTNWR_done, set by hardware when MTNWR + * is done, clear by write 1 by code;these two + * bits have nothing to do with + * DI_INTR_CTRL[16](NRW irq mask, 0 to enable + * irq) and DI_INTR_CTRL[17] + * (MTN irq mask, 0 to enable irq).two + * interrupts are raised if both + * DI_INTR_CTRL[16] and DI_INTR_CTRL[17] are 0 + */ + if ( + ((data32 & 0x1) && + ((di_pre_stru.enable_mtnwr == 0) + || (data32 & + 0x2))) || + (di_pre_stru.pre_de_clear_flag == 2)) { + RDMA_WR(DI_INTR_CTRL, data32); +#endif + pre_process_time = + di_pre_stru.pre_de_busy_timer_count; + pre_de_done_buf_config(); + + di_pre_stru.pre_de_process_done = 0; + di_pre_stru.pre_de_clear_flag = 0; +#ifdef CHECK_DI_DONE + } +#endif + } else if (di_pre_stru.pre_de_clear_flag == 1) { + di_lock_irqfiq_save( + irq_flag2, fiq_flag); + pre_de_done_buf_clear(); + di_unlock_irqfiq_restore( + irq_flag2, fiq_flag); + di_pre_stru.pre_de_process_done = 0; + di_pre_stru.pre_de_clear_flag = 0; + } + } + + di_lock_irqfiq_save(irq_flag2, fiq_flag); + while (check_recycle_buf() & 1) + ; + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + if (!bypass_direct) { + if ((di_pre_stru.pre_de_busy == 0) && + (di_pre_stru.pre_de_process_done == 0)) { + if ((pre_run_flag == DI_RUN_FLAG_RUN) || + (pre_run_flag == DI_RUN_FLAG_STEP)) { + if (pre_run_flag == DI_RUN_FLAG_STEP) + pre_run_flag = + DI_RUN_FLAG_STEP_DONE; + if (pre_de_buf_config()) + pre_de_process(); + } + } + while (process_post_vframe()) + ; + } + if ((post_wr_en && post_wr_surpport)) { + if (di_post_stru.post_de_busy == 0 && + di_post_stru.de_post_process_done) { + post_de_done_buf_config(); + di_post_stru.de_post_process_done = 0; + } + di_post_process(); + } + +#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_unlock_irqrestore(&plist_lock, flags); +#endif + } +} +static unsigned int nr_done_check_cnt = 5; +module_param_named(nr_done_check_cnt, nr_done_check_cnt, uint, 0644); +void di_timer_handle(struct work_struct *work) +{ + + if (di_pre_stru.pre_de_busy) { + di_pre_stru.pre_de_busy_timer_count++; + if (di_pre_stru.pre_de_busy_timer_count >= nr_done_check_cnt) { + enable_di_pre_mif(0); + di_pre_stru.pre_de_busy_timer_count = 0; + di_pre_stru.pre_de_irq_timeout_count++; + if (timeout_miss_policy == 0) { + di_pre_stru.pre_de_process_done = 1; + di_pre_stru.pre_de_busy = 0; + di_pre_stru.pre_de_clear_flag = 2; + } else if (timeout_miss_policy == 1) { + di_pre_stru.pre_de_clear_flag = 1; + di_pre_stru.pre_de_busy = 0; + } /* else if (timeout_miss_policy == 2) { + * } + */ + pr_info("***** DI ****** wait %d pre_de_irq timeout\n", + di_pre_stru.field_count_for_cont); + } + } else { + di_pre_stru.pre_de_busy_timer_count = 0; + } + + /* if(force_trig){ */ + force_trig_cnt++; + trigger_pre_di_process(TRIGGER_PRE_BY_TIMER); + /* } */ + + if (force_recovery) { + if (recovery_flag || (force_recovery & 0x2)) { + force_recovery_count++; + if (init_flag && mem_flag) { + pr_dbg("====== DI force recovery =========\n"); + force_recovery &= (~0x2); + dis2_di(); + recovery_flag = 0; + } + } + } +} + +static int di_task_handle(void *data) +{ + int ret = 0; + + while (1) { + ret = down_interruptible(&di_sema); + if (active_flag) { + if ((di_pre_stru.unreg_req_flag || + di_pre_stru.force_unreg_req_flag || + di_pre_stru.disable_req_flag) && + (di_pre_stru.pre_de_busy == 0)) + di_unreg_process(); + if (di_pre_stru.reg_req_flag_irq || + di_pre_stru.reg_req_flag) { + di_reg_process(); + di_pre_stru.reg_req_flag = 0; + di_pre_stru.reg_req_flag_irq = 0; + } + #ifdef CONFIG_CMA + if (di_pre_stru.cma_alloc_req) { + di_cma_alloc(); + di_pre_stru.cma_alloc_req = 0; + di_pre_stru.cma_alloc_done = 1; + mem_flag = 1; + } + if (di_pre_stru.cma_release_req) { + di_cma_release(); + di_pre_stru.cma_release_req = 0; + di_pre_stru.cma_alloc_done = 0; + mem_flag = 0; + } + #endif + } + } + + return 0; +} + +static irqreturn_t timer_irq(int irq, void *dev_instance) +{ +/* unsigned int data32; */ + int i; + + if (active_flag) { + if (di_pre_stru.unreg_req_flag_irq) + di_unreg_process_irq(); + if (init_flag == 0 && di_pre_stru.reg_req_flag_irq == 0) + di_reg_process_irq(); + } + + for (i = 0; i < 2; i++) + if (active_flag) + di_process(); + log_buffer_state("pro"); + return IRQ_HANDLED; +} +/* + * provider/receiver interface + */ + +/* unsigned int vf_keep_current(void);*/ +static int di_receiver_event_fun(int type, void *data, void *arg) +{ + int i; + ulong flags; + + if (type == VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR) { + return di_pre_stru.vdin2nr; + } else if (type == VFRAME_EVENT_PROVIDER_UNREG) { + pr_dbg("%s , is_bypass() %d trick_mode %d bypass_all %d\n", + __func__, is_bypass(NULL), trick_mode, bypass_all); + + if ((Rd(DI_IF1_GEN_REG) & 0x1) && get_blackout_policy()) + /* disable post di, so can call vf_keep_current() + * to keep displayed vframe + */ + pr_info("DI: disabled, not keep buffer.\n"); + + pr_dbg("%s: vf_notify_receiver unreg\n", __func__); + + di_pre_stru.unreg_req_flag = 1; + provider_vframe_level = 0; + vdin_source_flag = 0; + trigger_pre_di_process(TRIGGER_PRE_BY_PROVERDER_UNREG); + while (di_pre_stru.unreg_req_flag) + usleep_range(10000, 10001); +#ifdef SUPPORT_MPEG_TO_VDIN + if (mpeg2vdin_flag) { + struct vdin_arg_s vdin_arg; + struct vdin_v4l2_ops_s *vdin_ops = get_vdin_v4l2_ops(); + + vdin_arg.cmd = VDIN_CMD_MPEGIN_STOP; + if (vdin_ops->tvin_vdin_func) + vdin_ops->tvin_vdin_func(0, &vdin_arg); + + mpeg2vdin_flag = 0; + } +#endif + bypass_state = 1; +#ifdef RUN_DI_PROCESS_IN_IRQ + if (vdin_source_flag) + DI_Wr_reg_bits(VDIN_WR_CTRL, 0x3, 24, 3); + +#endif + } else if (type == VFRAME_EVENT_PROVIDER_RESET) { + di_blocking = 1; + + pr_dbg("%s: VFRAME_EVENT_PROVIDER_RESET\n", __func__); + + goto light_unreg; + } else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG) { + di_blocking = 1; + + pr_dbg("%s: vf_notify_receiver ligth unreg\n", __func__); + +light_unreg: + provider_vframe_level = 0; + + spin_lock_irqsave(&plist_lock, flags); + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + + if (vframe_in[i]) + pr_dbg("DI:clear vframe_in[%d]\n", i); + + vframe_in[i] = NULL; + } + spin_unlock_irqrestore(&plist_lock, flags); + di_blocking = 0; + } else if (type == VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME) { + unsigned char vf_put_flag = 0; + + pr_dbg( + "%s:VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME\n", + __func__); + + provider_vframe_level = 0; + +/* + * do not display garbage when 2d->3d or 3d->2d + */ + spin_lock_irqsave(&plist_lock, flags); + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + if (vframe_in[i]) { + vf_put(vframe_in[i], VFM_NAME); + pr_dbg("DI:clear vframe_in[%d]\n", i); + vf_put_flag = 1; + } + vframe_in[i] = NULL; + } + if (vf_put_flag) + vf_notify_provider(VFM_NAME, + VFRAME_EVENT_RECEIVER_PUT, NULL); + + spin_unlock_irqrestore(&plist_lock, flags); + } else if (type == VFRAME_EVENT_PROVIDER_VFRAME_READY) { + provider_vframe_level++; + trigger_pre_di_process(TRIGGER_PRE_BY_VFRAME_READY); + +#ifdef RUN_DI_PROCESS_IN_IRQ +#define INPUT2PRE_2_BYPASS_SKIP_COUNT 4 + if (active_flag && vdin_source_flag) { + if (is_bypass(NULL)) { + if (di_pre_stru.pre_de_busy == 0) { + DI_Wr_reg_bits(VDIN_WR_CTRL, + 0x3, 24, 3); + di_pre_stru.vdin2nr = 0; + } + if (di_pre_stru.bypass_start_count < + INPUT2PRE_2_BYPASS_SKIP_COUNT) { + vframe_t *vframe_tmp = vf_get(VFM_NAME); + + if (vframe_tmp != NULL) { + vf_put(vframe_tmp, VFM_NAME); + vf_notify_provider(VFM_NAME, + VFRAME_EVENT_RECEIVER_PUT, + NULL); + } + di_pre_stru.bypass_start_count++; + } + } else if (is_input2pre()) { + di_pre_stru.bypass_start_count = 0; + if ((di_pre_stru.pre_de_busy != 0) && + (input2pre_miss_policy == 1 && + frame_count < 30)) { + di_pre_stru.pre_de_clear_flag = 1; + di_pre_stru.pre_de_busy = 0; + input2pre_buf_miss_count++; + } + + if (di_pre_stru.pre_de_busy == 0) { + DI_Wr_reg_bits(VDIN_WR_CTRL, + 0x5, 24, 3); + di_pre_stru.vdin2nr = 1; + di_process(); + log_buffer_state("pr_"); + if (di_pre_stru.pre_de_busy == 0) + input2pre_proc_miss_count++; + } else { + vframe_t *vframe_tmp = vf_get(VFM_NAME); + + if (vframe_tmp != NULL) { + vf_put(vframe_tmp, VFM_NAME); + vf_notify_provider(VFM_NAME, + VFRAME_EVENT_RECEIVER_PUT, + NULL); + } + input2pre_buf_miss_count++; + if ((di_pre_stru.cur_width > 720 && + di_pre_stru.cur_height > 576) || + (input2pre_throw_count & 0x10000)) + di_pre_stru.pre_throw_flag = + input2pre_throw_count & + 0xffff; + } + } else { + if (di_pre_stru.pre_de_busy == 0) { + DI_Wr_reg_bits(VDIN_WR_CTRL, + 0x3, 24, 3); + di_pre_stru.vdin2nr = 0; + } + di_pre_stru.bypass_start_count = + INPUT2PRE_2_BYPASS_SKIP_COUNT; + } + } +#endif + } else if (type == VFRAME_EVENT_PROVIDER_QUREY_STATE) { + /*int in_buf_num = 0;*/ + struct vframe_states states; + + if (recovery_flag) + return RECEIVER_INACTIVE; +#if 1/*fix for ucode reset method be break by di.20151230*/ + di_vf_states(&states, NULL); + if (states.buf_avail_num > 0) + return RECEIVER_ACTIVE; + + if (vf_notify_receiver( + VFM_NAME, + VFRAME_EVENT_PROVIDER_QUREY_STATE, + NULL) == RECEIVER_ACTIVE) + return RECEIVER_ACTIVE; + return RECEIVER_INACTIVE; + +#else + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + if (vframe_in[i] != NULL) + in_buf_num++; + if (bypass_state == 1) { + if (in_buf_num > 1) + return RECEIVER_ACTIVE; + else + return RECEIVER_INACTIVE; + } else { + if (in_buf_num > 0) + return RECEIVER_ACTIVE; + else + return RECEIVER_INACTIVE; + } +#endif + } else if (type == VFRAME_EVENT_PROVIDER_REG) { + char *provider_name = (char *)data; + char *receiver_name = NULL; + + bypass_state = 0; + di_pre_stru.reg_req_flag = 1; + pr_dbg("%s: vframe provider reg\n", __func__); + trigger_pre_di_process(TRIGGER_PRE_BY_PROVERDER_REG); + while (di_pre_stru.reg_req_flag) + usleep_range(10000, 10001); + + aml_cbus_update_bits(ISA_TIMER_MUX, 1 << 14, 0 << 14); + aml_cbus_update_bits(ISA_TIMER_MUX, 3 << 4, 0 << 4); + aml_cbus_update_bits(ISA_TIMER_MUX, 1 << 18, 1 << 18); + aml_write_cbus(ISA_TIMERC, 1); + + if (strncmp(provider_name, "vdin", 4) == 0) { + vdin_source_flag = 1; + } else { + vdin_source_flag = 0; + pre_urgent = 0; + } + receiver_name = vf_get_receiver_name(VFM_NAME); + if (receiver_name) { + if (!strcmp(receiver_name, "amvideo")) { + di_post_stru.run_early_proc_fun_flag = 0; + receiver_is_amvideo = 1; + /* pr_info("set run_early_proc_fun_flag to 1\n"); */ + } else { + di_post_stru.run_early_proc_fun_flag = 1; + receiver_is_amvideo = 0; + pr_info("set run_early_proc_fun_flag to 1\n"); + } + } else { + pr_info("%s error receiver is null.\n", __func__); + } + } +#ifdef DET3D + else if (type == VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE) { + int flag = (long)data; + + di_pre_stru.vframe_interleave_flag = flag; + } +#endif + else if (type == VFRAME_EVENT_PROVIDER_FR_HINT) { + vf_notify_receiver(VFM_NAME, + VFRAME_EVENT_PROVIDER_FR_HINT, data); + } else if (type == VFRAME_EVENT_PROVIDER_FR_END_HINT) { + vf_notify_receiver(VFM_NAME, + VFRAME_EVENT_PROVIDER_FR_END_HINT, data); + } + + return 0; +} + +static void fast_process(void) +{ + int i; + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + + if (active_flag && is_bypass(NULL) && (BYPASS_GET_MAX_BUF_NUM <= 1) && + init_flag && mem_flag && (recovery_flag == 0) && + (dump_state_flag == 0)) { + if (vf_peek(VFM_NAME) == NULL) + return; + + for (i = 0; i < 2; i++) { + spin_lock_irqsave(&plist_lock, flags); + if (di_pre_stru.pre_de_process_done) { + pre_de_done_buf_config(); + di_pre_stru.pre_de_process_done = 0; + } + + di_lock_irqfiq_save(irq_flag2, fiq_flag); + while (check_recycle_buf() & 1) + ; + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + + if ((di_pre_stru.pre_de_busy == 0) && + (di_pre_stru.pre_de_process_done == 0)) { + if ((pre_run_flag == DI_RUN_FLAG_RUN) || + (pre_run_flag == DI_RUN_FLAG_STEP)) { + if (pre_run_flag == DI_RUN_FLAG_STEP) + pre_run_flag = + DI_RUN_FLAG_STEP_DONE; + if (pre_de_buf_config()) + pre_de_process(); + } + } + while (process_post_vframe()) + ; + + spin_unlock_irqrestore(&plist_lock, flags); + } + } +} + +static vframe_t *di_vf_peek(void *arg) +{ + vframe_t *vframe_ret = NULL; + struct di_buf_s *di_buf = NULL; + + video_peek_cnt++; + if ((init_flag == 0) || (mem_flag == 0) || recovery_flag || + di_blocking || di_pre_stru.unreg_req_flag || dump_state_flag) + return NULL; + if ((run_flag == DI_RUN_FLAG_PAUSE) || + (run_flag == DI_RUN_FLAG_STEP_DONE)) + return NULL; + + log_buffer_state("pek"); + + if (bypass_direct) + return vf_peek(VFM_NAME); + + fast_process(); +#ifdef SUPPORT_START_FRAME_HOLD + if ((disp_frame_count == 0) && (is_bypass(NULL) == 0)) { + int ready_count = list_count(QUEUE_POST_READY); + + if (ready_count > start_frame_hold_count) { + di_buf = get_di_buf_head(QUEUE_POST_READY); + if (di_buf) + vframe_ret = di_buf->vframe; + } + } else +#endif + { + if (!queue_empty(QUEUE_POST_READY)) { + di_buf = get_di_buf_head(QUEUE_POST_READY); + if (di_buf) + vframe_ret = di_buf->vframe; + } + } +#ifdef DI_BUFFER_DEBUG + if (vframe_ret) + di_print("%s: %s[%d]:%x\n", __func__, + vframe_type_name[di_buf->type], + di_buf->index, vframe_ret); +#endif + if (force_duration_0) { + if (vframe_ret) + vframe_ret->duration = 0; + } + return vframe_ret; +} +/*recycle the buffer for keeping buffer*/ +void recycle_keep_buffer(void) +{ + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + int i = 0; + + if ((used_post_buf_index != -1) && (new_keep_last_frame_enable)) { + if (di_buf_post[used_post_buf_index].type == VFRAME_TYPE_POST) { + pr_dbg("%s recycle keep cur di_buf %d (", + __func__, used_post_buf_index); + di_lock_irqfiq_save(irq_flag2, fiq_flag); + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) { + if ( + di_buf_post[used_post_buf_index]. + di_buf_dup_p[i]) { + queue_in( + di_buf_post[used_post_buf_index]. + di_buf_dup_p[i], + QUEUE_RECYCLE); + pr_dbg(" %d ", + di_buf_post[used_post_buf_index] + .di_buf_dup_p[i]->index); + } + } + queue_in(&di_buf_post[used_post_buf_index], + QUEUE_POST_FREE); + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + pr_dbg(")\n"); + } + used_post_buf_index = -1; + } +} +static vframe_t *di_vf_get(void *arg) +{ + vframe_t *vframe_ret = NULL; + struct di_buf_s *di_buf = NULL; + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + + if ((init_flag == 0) || (mem_flag == 0) || recovery_flag || + di_blocking || di_pre_stru.unreg_req_flag || dump_state_flag) + return NULL; + + if ((run_flag == DI_RUN_FLAG_PAUSE) || + (run_flag == DI_RUN_FLAG_STEP_DONE)) + return NULL; + + if (bypass_direct) + return vf_get(VFM_NAME); + + +#ifdef SUPPORT_START_FRAME_HOLD + if ((disp_frame_count == 0) && (is_bypass(NULL) == 0)) { + int ready_count = list_count(QUEUE_POST_READY); + + if (ready_count > start_frame_hold_count) + goto get_vframe; + } else +#endif + if (!queue_empty(QUEUE_POST_READY)) { +#ifdef SUPPORT_START_FRAME_HOLD +get_vframe: +#endif + log_buffer_state("ge_"); + di_lock_irqfiq_save(irq_flag2, fiq_flag); + + di_buf = get_di_buf_head(QUEUE_POST_READY); + queue_out(di_buf); + queue_in(di_buf, QUEUE_DISPLAY); /* add it into display_list */ + + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + + if (di_buf) { + vframe_ret = di_buf->vframe; + + if ((post_wr_en && post_wr_surpport) && + (di_buf->process_fun_index != PROCESS_FUN_NULL)) { + config_canvas_idx(di_buf, + di_post_idx[di_post_stru.canvas_id][5], -1); + vframe_ret->canvas0Addr = di_buf->nr_canvas_idx; + vframe_ret->canvas1Addr = di_buf->nr_canvas_idx; + vframe_ret->early_process_fun = NULL; + vframe_ret->process_fun = NULL; + } + } + disp_frame_count++; + if (run_flag == DI_RUN_FLAG_STEP) + run_flag = DI_RUN_FLAG_STEP_DONE; + + log_buffer_state("get"); + } + if (vframe_ret) { + di_print("%s: %s[%d]:%x %u ms\n", __func__, + vframe_type_name[di_buf->type], di_buf->index, vframe_ret, + jiffies_to_msecs(jiffies_64 - vframe_ret->ready_jiffies64)); + } + + if (force_duration_0) { + if (vframe_ret) + vframe_ret->duration = 0; + } + + if (!post_wr_en && di_post_stru.run_early_proc_fun_flag && vframe_ret) { + if (vframe_ret->early_process_fun == do_pre_only_fun) + vframe_ret->early_process_fun( + vframe_ret->private_data, vframe_ret); + } + atomic_set(&di_buf->di_cnt, 1); + return vframe_ret; +} + +static void di_vf_put(vframe_t *vf, void *arg) +{ + struct di_buf_s *di_buf = (struct di_buf_s *)vf->private_data; + ulong flags = 0, fiq_flag = 0, irq_flag2 = 0; + +/* struct di_buf_s *p = NULL; */ +/* int itmp = 0; */ + if ((init_flag == 0) || (mem_flag == 0) || recovery_flag || !vf) { + di_print("%s: 0x%p\n", __func__, vf); + return; + } + if (di_blocking) + return; + log_buffer_state("pu_"); + if (used_post_buf_index != -1) + recycle_keep_buffer(); + + if (!di_buf) + return vf_put(vf, VFM_NAME); + + if (di_buf->type == VFRAME_TYPE_POST) { + di_lock_irqfiq_save(irq_flag2, fiq_flag); + + if (is_in_queue(di_buf, QUEUE_DISPLAY)) { + if (!atomic_dec_and_test(&di_buf->di_cnt)) + di_print("%s,di_cnt > 0\n", __func__); + recycle_vframe_type_post(di_buf); + } else { + di_print("%s: %s[%d] not in display list\n", __func__, + vframe_type_name[di_buf->type], di_buf->index); + } + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); +#ifdef DI_BUFFER_DEBUG + recycle_vframe_type_post_print(di_buf, __func__, __LINE__); +#endif + } else { + di_lock_irqfiq_save(irq_flag2, fiq_flag); + queue_in(di_buf, QUEUE_RECYCLE); + di_unlock_irqfiq_restore(irq_flag2, fiq_flag); + + di_print("%s: %s[%d] =>recycle_list\n", __func__, + vframe_type_name[di_buf->type], di_buf->index); + } + + trigger_pre_di_process(TRIGGER_PRE_BY_PUT); +} + +static int di_event_cb(int type, void *data, void *private_data) +{ + if (type == VFRAME_EVENT_RECEIVER_FORCE_UNREG) { + pr_dbg("%s: VFRAME_EVENT_RECEIVER_FORCE_UNREG\n", __func__); + di_pre_stru.force_unreg_req_flag = 1; + provider_vframe_level = 0; + + trigger_pre_di_process(TRIGGER_PRE_BY_FORCE_UNREG); + while (di_pre_stru.force_unreg_req_flag) + usleep_range(1000, 1001); + } + return 0; +} + +static int di_vf_states(struct vframe_states *states, void *arg) +{ + if (!states) + return -1; + states->vf_pool_size = local_buf_num; + states->buf_free_num = list_count(QUEUE_LOCAL_FREE); + states->buf_avail_num = list_count(QUEUE_POST_READY); + states->buf_recycle_num = list_count(QUEUE_RECYCLE); + return 0; +} + +/***************************** + * di driver file_operations + * + ******************************/ +static int di_open(struct inode *node, struct file *file) +{ + di_dev_t *di_in_devp; + +/* Get the per-device structure that contains this cdev */ + di_in_devp = container_of(node->i_cdev, di_dev_t, cdev); + file->private_data = di_in_devp; + + return 0; +} + + +static int di_release(struct inode *node, struct file *file) +{ +/* di_dev_t *di_in_devp = file->private_data; */ + +/* Reset file pointer */ + +/* Release some other fields */ +/* ... */ + return 0; +} + +static const struct file_operations di_fops = { + .owner = THIS_MODULE, + .open = di_open, + .release = di_release, +/* .ioctl = di_ioctl, */ +}; + +static ssize_t +show_frame_format(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + + if (init_flag && mem_flag) + ret += sprintf(buf + ret, "%s\n", + di_pre_stru.cur_prog_flag + ? "progressive" : "interlace"); + + else + ret += sprintf(buf + ret, "%s\n", "null"); + + return ret; +} +static DEVICE_ATTR(frame_format, 0444, show_frame_format, NULL); + +static int rmem_di_device_init(struct reserved_mem *rmem, struct device *dev) +{ + di_dev_t *di_devp = dev_get_drvdata(dev); + + if (di_devp) { + di_devp->mem_start = rmem->base; + di_devp->mem_size = rmem->size; + if (!of_get_flat_dt_prop(rmem->fdt_node, "no-map", NULL)) + di_devp->flags |= DI_MAP_FLAG; + pr_dbg("di reveser memory 0x%lx, size %uMB.\n", + di_devp->mem_start, (di_devp->mem_size >> 20)); + return 0; + } +/* pr_dbg("di reveser memory 0x%x, size %u B.\n", + * rmem->base, rmem->size); + */ + return 1; +} + +static void rmem_di_device_release(struct reserved_mem *rmem, + struct device *dev) +{ + di_dev_t *di_devp = dev_get_drvdata(dev); + + if (di_devp) { + di_devp->mem_start = 0; + di_devp->mem_size = 0; + } +} +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA +unsigned int RDMA_RD_BITS(unsigned int adr, unsigned int start, + unsigned int len) +{ + if (de_devp->rdma_handle) + return rdma_read_reg(de_devp->rdma_handle, adr) & + (((1 << len) - 1) << start); + else + return Rd_reg_bits(adr, start, len); +} + +unsigned int RDMA_WR(unsigned int adr, unsigned int val) +{ + if (is_need_stop_reg(adr)) + return 0; + + if (de_devp->rdma_handle > 0 && di_pre_rdma_enable) { + if (di_pre_stru.field_count_for_cont < 1) + DI_Wr(adr, val); + else + rdma_write_reg(de_devp->rdma_handle, adr, val); + return 0; + } + + DI_Wr(adr, val); + return 1; +} + +unsigned int RDMA_RD(unsigned int adr) +{ + if (de_devp->rdma_handle > 0 && di_pre_rdma_enable) + return rdma_read_reg(de_devp->rdma_handle, adr); + else + return Rd(adr); +} + +unsigned int RDMA_WR_BITS(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len) +{ + if (is_need_stop_reg(adr)) + return 0; + + if (de_devp->rdma_handle > 0 && di_pre_rdma_enable) { + if (di_pre_stru.field_count_for_cont < 1) + DI_Wr_reg_bits(adr, val, start, len); + else + rdma_write_reg_bits(de_devp->rdma_handle, + adr, val, start, len); + return 0; + } + DI_Wr_reg_bits(adr, val, start, len); + return 1; +} +#else +unsigned int RDMA_RD_BITS(unsigned int adr, unsigned int start, + unsigned int len) +{ + return Rd_reg_bits(adr, start, len); +} +unsigned int RDMA_WR(unsigned int adr, unsigned int val) +{ + DI_Wr(adr, val); + return 1; +} + +unsigned int RDMA_RD(unsigned int adr) +{ + return Rd(adr); +} + +unsigned int RDMA_WR_BITS(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len) +{ + DI_Wr_reg_bits(adr, val, start, len); + return 1; +} +#endif + +static void set_di_flag(void) +{ + if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu()) { + mcpre_en = true; + pulldown_enable = 1; + di_pre_rdma_enable = false; + di_vscale_skip_enable = 4; + use_2_interlace_buff = 1; + pre_hold_line = 12; + if (nr10bit_surpport) + di_force_bit_mode = 10; + else + di_force_bit_mode = 8; + if (is_meson_txl_cpu()) { + full_422_pack = true; + tff_bff_enable = false; + dejaggy_enable = 0; + } + } else { + mcpre_en = false; + pulldown_enable = 0; + di_pre_rdma_enable = false; + di_vscale_skip_enable = 4; + use_2_interlace_buff = 0; + di_force_bit_mode = 8; + } + + if (di_pre_rdma_enable) { + pldn_dly = 1; + pldn_dly1 = 1; + tbbtff_dly = 1; + } else { + pldn_dly = 2; + pldn_dly1 = 2; + tbbtff_dly = 0; + } + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB)) + dnr_dm_en = true; +} + +static const struct reserved_mem_ops rmem_di_ops = { + .device_init = rmem_di_device_init, + .device_release = rmem_di_device_release, +}; + +static int __init rmem_di_setup(struct reserved_mem *rmem) +{ + rmem->ops = &rmem_di_ops; +/* rmem->priv = cma; */ + + di_pr_info( + "DI reserved memory: created CMA memory pool at %pa, size %ld MiB\n", + &rmem->base, (unsigned long)rmem->size / SZ_1M); + + return 0; +} +RESERVEDMEM_OF_DECLARE(di, "amlogic, di-mem", rmem_di_setup); +static int di_probe(struct platform_device *pdev) +{ + int ret = 0, i = 0;/* , offset = 0, size = 0; */ +/* struct resource *res_irq = NULL; */ + int buf_num_avail = 0; + struct di_dev_s *di_devp = NULL; + +/* const void *name = NULL; */ + di_pr_info("di_probe\n"); + di_devp = kmalloc(sizeof(struct di_dev_s), GFP_KERNEL); + if (!di_devp) { + pr_err("%s fail to allocate memory.\n", __func__); + goto fail_kmalloc_dev; + } + de_devp = di_devp; + memset(di_devp, 0, sizeof(struct di_dev_s)); + cdev_init(&(di_devp->cdev), &di_fops); + di_devp->cdev.owner = THIS_MODULE; + cdev_add(&(di_devp->cdev), di_devno, DI_COUNT); + di_devp->devt = MKDEV(MAJOR(di_devno), 0); + di_devp->dev = device_create(di_clsp, &pdev->dev, + di_devp->devt, di_devp, "di%d", 0); + + if (di_devp->dev == NULL) { + pr_error("device_create create error\n"); + ret = -EEXIST; + return ret; + } + dev_set_drvdata(di_devp->dev, di_devp); + platform_set_drvdata(pdev, di_devp); + of_reserved_mem_device_init(&pdev->dev); + ret = of_property_read_u32(pdev->dev.of_node, + "flag_cma", &(di_devp->flag_cma)); + if (ret) + pr_err("DI-%s: get flag_cma error.\n", __func__); + else + pr_info("DI-%s: flag_cma: %d\n", __func__, di_devp->flag_cma); + if (di_devp->flag_cma == 1) { +#ifdef CONFIG_CMA + di_devp->pdev = pdev; + di_devp->mem_size = dma_get_cma_size_int_byte(&pdev->dev); + pr_info("DI: CMA size 0x%x.\n", di_devp->mem_size); +#endif + mem_flag = 0; + } else { + mem_flag = 1; + } + di_devp->di_irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + di_devp->timerc_irq = irq_of_parse_and_map(pdev->dev.of_node, 1); + pr_info("di_irq:%d,timerc_irq:%d\n", + di_devp->di_irq, di_devp->timerc_irq); +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA +/* rdma handle */ + di_rdma_op.arg = di_devp; + di_devp->rdma_handle = rdma_register(&di_rdma_op, + di_devp, RDMA_TABLE_SIZE); +#endif + di_pr_info("%s allocate rdma channel %d.\n", __func__, + di_devp->rdma_handle); + + ret = of_property_read_u32(pdev->dev.of_node, + "buffer-size", &(di_devp->buffer_size)); + if (ret) + pr_err("DI-%s: get buffer size error.\n", __func__); + + ret = of_property_read_u32(pdev->dev.of_node, + "hw-version", &(di_devp->hw_version)); + if (ret) + pr_err("DI-%s: get hw version error.\n", __func__); + di_pr_info("DI hw version %u.\n", di_devp->hw_version); + + /* set flag to indicate that post_wr is surpportted */ + ret = of_property_read_u32(pdev->dev.of_node, + "post-wr-surpport", + &(di_devp->post_wr_surpport)); + if (ret) + post_wr_surpport = 0; + else + post_wr_surpport = di_devp->post_wr_surpport; + + ret = of_property_read_u32(pdev->dev.of_node, + "nr10bit-surpport", + &(di_devp->nr10bit_surpport)); + if (ret) + nr10bit_surpport = 0; + else + nr10bit_surpport = di_devp->nr10bit_surpport; + + memset(&di_post_stru, 0, sizeof(di_post_stru)); + di_post_stru.next_canvas_id = 1; +#ifdef DI_USE_FIXED_CANVAS_IDX + if (di_get_canvas()) { + pr_dbg("DI get canvas error.\n"); + ret = -EEXIST; + return ret; + } +#endif +/* call di_add_reg_cfg() */ + + di_add_reg_cfg_init(); + + device_create_file(di_devp->dev, &dev_attr_config); + device_create_file(di_devp->dev, &dev_attr_debug); + device_create_file(di_devp->dev, &dev_attr_dump_pic); + device_create_file(di_devp->dev, &dev_attr_log); + device_create_file(di_devp->dev, &dev_attr_status); + device_create_file(di_devp->dev, &dev_attr_provider_vframe_status); + device_create_file(di_devp->dev, &dev_attr_frame_format); + device_create_file(di_devp->dev, &dev_attr_pd_param); + device_create_file(di_devp->dev, &dev_attr_tvp_region); + +#ifdef NEW_DI_V4 + nr_init(di_devp->dev); +#endif +/* get resource as memory,irq...*/ +/* mem = &memobj; */ + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) + used_local_buf_index[i] = -1; + + used_post_buf_index = -1; + init_flag = 0; + reg_flag = 0; + field_count = 0; + +/* set start_frame_hold_count base on buffer size */ + di_devp->buf_num_avail = di_devp->mem_size / di_devp->buffer_size; + if (di_devp->buf_num_avail > MAX_LOCAL_BUF_NUM) + di_devp->buf_num_avail = MAX_LOCAL_BUF_NUM; + + buf_num_avail = di_devp->buf_num_avail; +/**/ + + vf_receiver_init(&di_vf_recv, VFM_NAME, &di_vf_receiver, NULL); + vf_reg_receiver(&di_vf_recv); + active_flag = 1; +/* data32 = (*P_A9_0_IRQ_IN1_INTR_STAT_CLR); */ + ret = request_irq(di_devp->di_irq, &de_irq, IRQF_SHARED, + "deinterlace", (void *)"deinterlace"); + + sema_init(&di_sema, 1); + di_sema_init_flag = 1; + + di_hw_init(); + + if (pulldown_enable) + FlmVOFSftInt(&pd_param); + + set_di_flag(); + +/* Disable MCDI when code does not surpport MCDI */ + if (!mcpre_en) + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 1); +/* timer */ + INIT_WORK(&di_pre_work, di_timer_handle); + init_timer(&di_pre_timer); + di_pre_timer.data = (ulong) &di_pre_timer; + di_pre_timer.function = di_pre_timer_cb; + di_pre_timer.expires = jiffies + DI_PRE_INTERVAL; + add_timer(&di_pre_timer); +/**/ + di_devp->task = kthread_run(di_task_handle, di_devp, "kthread_di"); + di_pr_info("%s here.\n", __func__); + + aml_cbus_update_bits(ISA_TIMER_MUX, 1 << 14, 0 << 14); + aml_cbus_update_bits(ISA_TIMER_MUX, 3 << 4, 0 << 4); + aml_cbus_update_bits(ISA_TIMER_MUX, 1 << 18, 1 << 18); + + ret = request_irq(di_devp->timerc_irq, &timer_irq, + IRQF_SHARED, "timerC", + (void *)"timerC"); + di_set_power_control(0, 0); + di_set_power_control(1, 0); +fail_kmalloc_dev: + return ret; +} + +static int di_remove(struct platform_device *pdev) +{ + struct di_dev_s *di_devp = NULL; + + di_devp = platform_get_drvdata(pdev); + + di_hw_uninit(); + di_devp->di_event = 0xff; + kthread_stop(di_devp->task); +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA +/* rdma handle */ + if (di_devp->rdma_handle > 0) + rdma_unregister(di_devp->rdma_handle); +#endif + + vf_unreg_provider(&di_vf_prov); + vf_unreg_receiver(&di_vf_recv); + + di_uninit_buf(); + di_set_power_control(0, 0); + di_set_power_control(1, 0); +/* Remove the cdev */ + device_remove_file(di_devp->dev, &dev_attr_config); + device_remove_file(di_devp->dev, &dev_attr_debug); + device_remove_file(di_devp->dev, &dev_attr_log); + device_remove_file(di_devp->dev, &dev_attr_dump_pic); + device_remove_file(di_devp->dev, &dev_attr_status); + + cdev_del(&di_devp->cdev); + + device_destroy(di_clsp, di_devno); + kfree(di_devp); +/* free drvdata */ + dev_set_drvdata(&pdev->dev, NULL); + platform_set_drvdata(pdev, NULL); + + return 0; +} + +#ifdef CONFIG_PM +static int save_init_flag; +static int save_mem_flag; +static int di_suspend(struct platform_device *pdev, pm_message_t state) +{ + aml_cbus_update_bits(ISA_TIMER_MUX, 1 << 18, 0 << 18); + + +/* fix suspend/resume crash problem */ + save_init_flag = init_flag; + save_mem_flag = mem_flag; + init_flag = 0; + mem_flag = 0; + field_count = 0; + if (di_pre_stru.di_inp_buf) { + if (vframe_in[di_pre_stru.di_inp_buf->index]) { + vf_put(vframe_in[di_pre_stru.di_inp_buf->index], + VFM_NAME); + vframe_in[di_pre_stru.di_inp_buf->index] = NULL; + vf_notify_provider(VFM_NAME, + VFRAME_EVENT_RECEIVER_PUT, NULL); + } + } + + + di_set_power_control(0, 0); + di_set_power_control(1, 0); + di_pr_info("di: di_suspend\n"); + return 0; +} + +static int di_resume(struct platform_device *pdev) +{ + init_flag = save_init_flag; + mem_flag = save_mem_flag; + if (init_flag && mem_flag) { + di_set_power_control(0, 1); + di_set_power_control(1, 1); + } + + aml_cbus_update_bits(ISA_TIMER_MUX, 1 << 14, 0 << 14); + aml_cbus_update_bits(ISA_TIMER_MUX, 3 << 4, 0 << 4); + aml_cbus_update_bits(ISA_TIMER_MUX, 1 << 18, 1 << 18); + aml_write_cbus(ISA_TIMERC, 1); + di_pr_info("di_hdmirx: resume module\n"); + return 0; +} +#endif + +/* #ifdef CONFIG_USE_OF */ +static const struct of_device_id amlogic_deinterlace_dt_match[] = { + { .compatible = "amlogic, deinterlace", }, + {}, +}; +/* #else */ +/* #define amlogic_deinterlace_dt_match NULL */ +/* #endif */ + +static struct platform_driver di_driver = { + .probe = di_probe, + .remove = di_remove, +#ifdef CONFIG_PM + .suspend = di_suspend, + .resume = di_resume, +#endif + .driver = { + .name = DEVICE_NAME, + .owner = THIS_MODULE, + .of_match_table = amlogic_deinterlace_dt_match, + } +}; + +static int __init di_module_init(void) +{ + int ret = 0; + + di_pr_info("%s ok.\n", __func__); + if (boot_init_flag & INIT_FLAG_NOT_LOAD) + return 0; + + ret = alloc_chrdev_region(&di_devno, 0, DI_COUNT, DEVICE_NAME); + if (ret < 0) { + pr_err("%s: failed to allocate major number\n", __func__); + goto fail_alloc_cdev_region; + } + di_pr_info("%s: major %d\n", __func__, MAJOR(di_devno)); + di_clsp = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(di_clsp)) { + ret = PTR_ERR(di_clsp); + pr_err("%s: failed to create class\n", __func__); + goto fail_class_create; + } + + ret = platform_driver_register(&di_driver); + if (ret != 0) { + pr_err("%s: failed to register driver\n", __func__); + goto fail_pdrv_register; + } + return 0; +fail_pdrv_register: + class_destroy(di_clsp); +fail_class_create: + unregister_chrdev_region(di_devno, DI_COUNT); +fail_alloc_cdev_region: + return ret; +} + + +static void __exit di_module_exit(void) +{ + class_destroy(di_clsp); + unregister_chrdev_region(di_devno, DI_COUNT); + platform_driver_unregister(&di_driver); +} + +module_init(di_module_init); +module_exit(di_module_exit); + +static char *next_token_ex(char *separator, char *buf, unsigned int size, + unsigned int offset, unsigned int *token_len, + unsigned int *token_offset) +{ + /* besides characters defined in separator, '\"' are used as + * separator; and any characters in '\"' will not act as separator + */ + char *pToken = NULL; + char last_separator = 0; + char trans_char_flag = 0; + + if (buf) { + for (; offset < size; offset++) { + int ii = 0; + char ch; + + if (buf[offset] == '\\') { + trans_char_flag = 1; + continue; + } + while (((ch = separator[ii]) != buf[offset]) && (ch)) + ii++; + if (ch) { + if (!pToken) { + continue; + } else { + if (last_separator != '"') { + *token_len = (unsigned int) + (buf + offset - pToken); + *token_offset = offset; + return pToken; + } + } + } else if (!pToken) { + if (trans_char_flag && (buf[offset] == '"')) + last_separator = buf[offset]; + pToken = &buf[offset]; + } else if ( + (trans_char_flag && (buf[offset] == '"')) && + (last_separator == '"')) { + *token_len = + (unsigned int)(buf + offset - pToken - 2); + *token_offset = offset + 1; + return pToken + 1; + } + trans_char_flag = 0; + } + if (pToken) { + *token_len = (unsigned int)(buf + offset - pToken); + *token_offset = offset; + } + } + return pToken; +} + +static int __init di_boot_para_setup(char *s) +{ + char separator[] = { ' ', ',', ';', 0x0 }; + char *token; + unsigned int token_len, token_offset, offset = 0; + int size = strlen(s); + + do { + token = next_token_ex(separator, s, size, + offset, &token_len, &token_offset); + if (token) { + if ((token_len == 3) && + (strncmp(token, "off", token_len) == 0)) { + boot_init_flag |= INIT_FLAG_NOT_LOAD; + pr_info("DI: NOT LOAD\n"); + } + } + offset = token_offset; + } while (token); + return 0; +} + +__setup("di=", di_boot_para_setup); + +module_param_named(bypass_direct, bypass_direct, bool, 0664); +module_param_named(bypass_all, bypass_all, int, 0664); +module_param_named(bypass_3d, bypass_3d, int, 0664); +module_param_named(bypass_trick_mode, bypass_trick_mode, int, 0664); +module_param_named(invert_top_bot, invert_top_bot, int, 0664); +module_param_named(skip_top_bot, skip_top_bot, int, 0664); +module_param_named(force_width, force_width, int, 0664); +module_param_named(prog_proc_config, prog_proc_config, int, 0664); +module_param_named(skip_wrong_field, skip_wrong_field, int, 0664); +module_param_named(start_frame_drop_count, start_frame_drop_count, int, 0664); +#ifdef SUPPORT_START_FRAME_HOLD +module_param_named(start_frame_hold_count, start_frame_hold_count, int, 0664); +#endif +module_param_named(same_field_top_count, same_field_top_count, + long, 0664); +module_param_named(same_field_bot_count, same_field_bot_count, + long, 0664); +module_param_named(same_field_source_flag_th, same_field_source_flag_th, + int, 0664); +MODULE_PARM_DESC(di_log_flag, "\n di log flag\n"); +module_param(di_log_flag, int, 0664); + +MODULE_PARM_DESC(di_debug_flag, "\n di debug flag\n"); +module_param(di_debug_flag, int, 0664); + +MODULE_PARM_DESC(buf_state_log_threshold, "\n buf_state_log_threshold\n"); +module_param(buf_state_log_threshold, int, 0664); + +MODULE_PARM_DESC(bypass_state, "\n bypass_state\n"); +module_param(bypass_state, uint, 0664); + +MODULE_PARM_DESC(force_bob_flag, "\n force_bob_flag\n"); +module_param(force_bob_flag, uint, 0664); + +MODULE_PARM_DESC(di_vscale_skip_enable, "\n di_vscale_skip_enable\n"); +module_param(di_vscale_skip_enable, uint, 0664); + +MODULE_PARM_DESC(di_vscale_skip_count, "\n di_vscale_skip_count\n"); +module_param(di_vscale_skip_count, int, 0664); + +MODULE_PARM_DESC(di_vscale_skip_count_real, "\n di_vscale_skip_count_real\n"); +module_param(di_vscale_skip_count_real, int, 0664); + +module_param_named(vpp_3d_mode, vpp_3d_mode, int, 0664); +#ifdef DET3D +MODULE_PARM_DESC(det3d_en, "\n det3d_enable\n"); +module_param(det3d_en, bool, 0664); +MODULE_PARM_DESC(det3d_mode, "\n det3d_mode\n"); +module_param(det3d_mode, uint, 0664); +#endif + +MODULE_PARM_DESC(pre_hold_line, "\n pre_hold_line\n"); +module_param(pre_hold_line, uint, 0664); + +MODULE_PARM_DESC(pre_urgent, "\n pre_urgent\n"); +module_param(pre_urgent, uint, 0664); + +MODULE_PARM_DESC(post_hold_line, "\n post_hold_line\n"); +module_param(post_hold_line, uint, 0664); + +MODULE_PARM_DESC(post_urgent, "\n post_urgent\n"); +module_param(post_urgent, uint, 0664); + +MODULE_PARM_DESC(force_duration_0, "\n force_duration_0\n"); +module_param(force_duration_0, uint, 0664); + +MODULE_PARM_DESC(di_printk_flag, "\n di_printk_flag\n"); +module_param(di_printk_flag, uint, 0664); + +MODULE_PARM_DESC(force_recovery, "\n force_recovery\n"); +module_param(force_recovery, uint, 0664); + +module_param_named(force_recovery_count, force_recovery_count, uint, 0664); +module_param_named(pre_process_time_force, pre_process_time_force, uint, 0664); +module_param_named(pre_process_time, pre_process_time, uint, 0664); +module_param_named(bypass_post, bypass_post, uint, 0664); +module_param_named(post_wr_en, post_wr_en, bool, 0664); +module_param_named(post_wr_surpport, post_wr_surpport, uint, 0664); +module_param_named(bypass_post_state, bypass_post_state, uint, 0664); +module_param_named(force_update_post_reg, force_update_post_reg, uint, 0664); +module_param_named(update_post_reg_count, update_post_reg_count, uint, 0664); +/* n debug for progress interlace mixed source */ +module_param_named(use_2_interlace_buff, use_2_interlace_buff, int, 0664); +module_param_named(debug_blend_mode, debug_blend_mode, int, 0664); +MODULE_PARM_DESC(debug_blend_mode, "\n force post blend mode\n"); +module_param_named(nr10bit_surpport, nr10bit_surpport, uint, 0664); +module_param_named(di_stop_reg_flag, di_stop_reg_flag, uint, 0664); +module_param_array(di_stop_reg_addr, uint, &num_di_stop_reg_addr, + 0664); +module_param_named(static_pic_threshold, static_pic_threshold, int, 0664); +module_param_named(mcpre_en, mcpre_en, bool, 0664); +#ifdef NEW_DI_V4 +module_param_named(dnr_en, dnr_en, bool, 0664); +#endif +module_param_named(check_start_drop_prog, check_start_drop_prog, bool, 0664); +module_param_named(overturn, overturn, bool, 0664); +module_param_named(queue_print_flag, queue_print_flag, int, 0664); +module_param_named(full_422_pack, full_422_pack, bool, 0644); +#ifdef DEBUG_SUPPORT + +#ifdef RUN_DI_PROCESS_IN_IRQ +module_param_named(input2pre, input2pre, uint, 0664); +module_param_named(input2pre_buf_miss_count, input2pre_buf_miss_count, + uint, 0664); +module_param_named(input2pre_proc_miss_count, input2pre_proc_miss_count, + uint, 0664); +module_param_named(input2pre_miss_policy, input2pre_miss_policy, uint, 0664); +module_param_named(input2pre_throw_count, input2pre_throw_count, uint, 0664); +#endif + +module_param_named(timeout_miss_policy, timeout_miss_policy, uint, 0664); +module_param_named(pldn_pst_wver, pldn_pst_wver, uint, 0644); +module_param_named(mpeg2vdin_en, mpeg2vdin_en, int, 0664); +module_param_named(mpeg2vdin_flag, mpeg2vdin_flag, int, 0664); +module_param_named(di_pre_rdma_enable, di_pre_rdma_enable, uint, 0664); +module_param_named(pldn_dly, pldn_dly, uint, 0644); +module_param_named(tbbtff_dly, tbbtff_dly, uint, 0644); +module_param_named(pldn_dly1, pldn_dly1, uint, 0644); +module_param_named(flm22_sure_num, flm22_sure_num, uint, 0644); +module_param_named(flm22_glbpxlnum_rat, flm22_glbpxlnum_rat, uint, 0644); +module_param_named(bypass_pre, bypass_pre, int, 0664); +module_param_named(frame_count, frame_count, int, 0664); +module_param_named(same_w_r_canvas_count, same_w_r_canvas_count, long, 0664); +#endif +MODULE_DESCRIPTION("AMLOGIC DEINTERLACE driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("1.0.0"); diff --git a/drivers/amlogic/media/deinterlace/deinterlace.h b/drivers/amlogic/media/deinterlace/deinterlace.h new file mode 100644 index 000000000000..d06a4b033ada --- /dev/null +++ b/drivers/amlogic/media/deinterlace/deinterlace.h @@ -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 +#include +#include +#include +#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<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 diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.c b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c new file mode 100644 index 000000000000..0159a1d60e1d --- /dev/null +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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); + } + } +} + diff --git a/drivers/amlogic/media/deinterlace/deinterlace_dbg.h b/drivers/amlogic/media/deinterlace/deinterlace_dbg.h new file mode 100644 index 000000000000..ded85378e31e --- /dev/null +++ b/drivers/amlogic/media/deinterlace/deinterlace_dbg.h @@ -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 +#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); + diff --git a/drivers/amlogic/media/deinterlace/deinterlace_hw.c b/drivers/amlogic/media/deinterlace/deinterlace_hw.c new file mode 100644 index 000000000000..bccfae3bc20e --- /dev/null +++ b/drivers/amlogic/media/deinterlace/deinterlace_hw.c @@ -0,0 +1,2082 @@ +/* + * drivers/amlogic/media/deinterlace/deinterlace_hw.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +/* #include */ +#include "deinterlace.h" +#include "register.h" +#ifdef DET3D +#include "detect3d.h" +#endif +#include "nr.h" + +#ifndef DI_CHAN2_CANVAS +#define DI_CHAN2_CANVAS DI_CHAN2_CANVAS0 +#endif +#ifndef DI_CHAN2_LUMA_X +#define DI_CHAN2_LUMA_X DI_CHAN2_LUMA_X0 +#endif +#ifndef DI_CHAN2_LUMA_Y +#define DI_CHAN2_LUMA_Y DI_CHAN2_LUMA_Y0 +#endif +#ifndef DI_CHAN2_LUMA_RPT_PAT +#define DI_CHAN2_LUMA_RPT_PAT DI_CHAN2_LUMA0_RPT_PAT +#endif + +uint di_mtn_1_ctrl1 = 0xa0202015; +uint mtn_ctrl1; + +static bool cue_enable; + +pd_win_prop_t pd_win_prop[MAX_WIN_NUM]; + +static bool frame_dynamic; +MODULE_PARM_DESC(frame_dynamic, "\n frame_dynamic\n"); +module_param(frame_dynamic, bool, 0664); + +static bool frame_dynamic_dbg; +MODULE_PARM_DESC(frame_dynamic_dbg, "\n frame_dynamic_dbg\n"); +module_param(frame_dynamic_dbg, bool, 0664); + +static int frame_dynamic_level; +MODULE_PARM_DESC(frame_dynamic_level, "\n frame_dynamic_level\n"); +module_param(frame_dynamic_level, int, 0664); + +MODULE_PARM_DESC(cue_enable, "\n cue_enable\n"); +module_param(cue_enable, bool, 0664); + +static unsigned short mcen_mode = 1; +MODULE_PARM_DESC(mcen_mode, "\n mcen mode\n"); +module_param(mcen_mode, ushort, 0664); +static unsigned short mcuv_en = 1; +MODULE_PARM_DESC(mcuv_en, "\n blend mcuv enable\n"); +module_param(mcuv_en, ushort, 0664); +static unsigned short mcdebug_mode; +MODULE_PARM_DESC(mcdebug_mode, "\n mcdi mcdebugmode\n"); +module_param(mcdebug_mode, ushort, 0664); + +static unsigned short debug_blend_mode_ctrl = 0xff; +MODULE_PARM_DESC(debug_blend_mode_ctrl, "\n debug blend mode ctrl\n"); +module_param(debug_blend_mode_ctrl, ushort, 0664); +/* + * 0: use vframe->bitdepth, + * 8: froce to 8 bit mode. + * 10: froce to 10 bit mode and enable nr 10 bit. + */ +unsigned int di_force_bit_mode = 10; +module_param(di_force_bit_mode, uint, 0664); +MODULE_PARM_DESC(di_force_bit_mode, "force DI bit mode to 8 or 10 bit"); + +static unsigned short mc_pre_flag = 2; +MODULE_PARM_DESC(mc_pre_flag, "\n mc per/forward flag\n"); +module_param(mc_pre_flag, ushort, 0664); + +#ifdef DET3D +static unsigned int det3d_cfg; +module_param(det3d_cfg, uint, 0664); +MODULE_PARM_DESC(det3d_cfg, "det3d_cfg"); +#endif + +static int vdin_en; + +static void set_di_inp_fmt_more( + unsigned int repeat_l0_en, + int hz_yc_ratio, /* 2bit */ + int hz_ini_phase, /* 4bit */ + int vfmt_en, + int vt_yc_ratio, /* 2bit */ + int vt_ini_phase, /* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ); + +static void set_di_inp_mif(struct DI_MIF_s *mif, int urgent, int hold_line); + +static void set_di_mem_fmt_more( + int hfmt_en, + int hz_yc_ratio, /* 2bit */ + int hz_ini_phase, /* 4bit */ + int vfmt_en, + int vt_yc_ratio, /* 2bit */ + int vt_ini_phase, /* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ); + +static void set_di_mem_mif(struct DI_MIF_s *mif, int urgent, int hold_line); + +static void set_di_if0_fmt_more( + int hfmt_en, + int hz_yc_ratio, /* 2bit */ + int hz_ini_phase, /* 4bit */ + int vfmt_en, + int vt_yc_ratio, /* 2bit */ + int vt_ini_phase, /* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ); + +static void set_di_if1_fmt_more( + int hfmt_en, + int hz_yc_ratio, /* 2bit */ + int hz_ini_phase, /* 4bit */ + int vfmt_en, + int vt_yc_ratio, /* 2bit */ + int vt_ini_phase, /* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ); + +static void set_di_if1_mif(struct DI_MIF_s *mif, int urgent, int hold_line); + +static void set_di_chan2_mif(struct DI_MIF_s *mif, int urgent, int hold_line); + +static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent, int hold_line); + +#if (defined NEW_DI_V2 && !defined NEW_DI_TV) +static void ma_di_init(void) +{ + /* 420->422 chrome difference is large motion is large,flick */ + DI_Wr(DI_MTN_1_CTRL4, 0x01800880); + DI_Wr(DI_MTN_1_CTRL7, 0x0a800480); + /* ei setting */ + DI_Wr(DI_EI_CTRL0, 0x00ff0100); + DI_Wr(DI_EI_CTRL1, 0x5a0a0f2d); + DI_Wr(DI_EI_CTRL2, 0x050a0a5d); + DI_Wr(DI_EI_CTRL3, 0x80000013); + /* mtn setting */ + DI_Wr(DI_MTN_1_CTRL1, 0xa0202015); + #if 0 + /* no use from g9tv */ + DI_Wr(DI_MTN_CTRL, 0xe228c440); + DI_Wr(DI_BLEND_CTRL1, 0xc4402840); + DI_Wr(DI_BLEND_CTRL2, 0x430); + #endif +} +#endif + +static void mc_di_param_init(void) +{ + DI_Wr(MCDI_CHK_EDGE_GAIN_OFFST, 0x4f6124); + DI_Wr(MCDI_LMV_RT, 0x7455); + DI_Wr(MCDI_LMV_GAINTHD, 0x6014d409); + DI_Wr(MCDI_REL_DET_LPF_MSK_22_30, 0x0a010001); + DI_Wr(MCDI_REL_DET_LPF_MSK_31_34, 0x01010101); +} + +static void init_field_mode(void) +{ + DI_Wr(DIPD_COMB_CTRL0, 0x02400210); + DI_Wr(DIPD_COMB_CTRL1, 0x88080808); + DI_Wr(DIPD_COMB_CTRL2, 0x41041008); + DI_Wr(DIPD_COMB_CTRL3, 0x00008053); + DI_Wr(DIPD_COMB_CTRL4, 0x20070002); + DI_Wr(DIPD_COMB_CTRL5, 0x04040804); +} + +void di_hw_init(void) +{ +#ifdef NEW_DI_V1 + unsigned short fifo_size_vpp = 0xc0; + unsigned short fifo_size_di = 0xc0; +#endif +#ifdef NEW_DI_V1 + switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_ON); + /* enable old DI mode for m6tv */ + if (is_meson_gxtvbb_cpu() || is_meson_gxl_cpu() || is_meson_gxm_cpu()) + DI_Wr(DI_CLKG_CTRL, 0xffff0001); + else + DI_Wr(DI_CLKG_CTRL, 0x1); /* di no clock gate */ + + if (is_meson_txl_cpu()) { + /* vpp fifo max size on txl :128*3=384[0x180] */ + /* di fifo max size on txl :96*3=288[0x120] */ + fifo_size_vpp = 0x180; + fifo_size_di = 0x120; + } + DI_Wr(VD1_IF0_LUMA_FIFO_SIZE, fifo_size_vpp); + DI_Wr(VD2_IF0_LUMA_FIFO_SIZE, fifo_size_vpp); + /* 1a83 is vd2_if0_luma_fifo_size */ + DI_Wr(DI_INP_LUMA_FIFO_SIZE, fifo_size_di); + /* 17d8 is DI_INP_luma_fifo_size */ + DI_Wr(DI_MEM_LUMA_FIFO_SIZE, fifo_size_di); + /* 17e5 is DI_MEM_luma_fifo_size */ + DI_Wr(DI_IF1_LUMA_FIFO_SIZE, fifo_size_di); + /* 17f2 is DI_IF1_luma_fifo_size */ + DI_Wr(DI_CHAN2_LUMA_FIFO_SIZE, fifo_size_di); + /* 17b3 is DI_chan2_luma_fifo_size */ +#endif + DI_Wr(DI_PRE_HOLD, (1 << 31) | (31 << 16) | 31); + + /* nr default setting */ + di_nr_init(); +#if (defined NEW_DI_V2 && !defined NEW_DI_TV) + ma_di_init(); +#endif + + if (pulldown_enable) + init_field_mode(); + + if (mcpre_en) + mc_di_param_init(); + + DI_Wr(DI_CLKG_CTRL, 0x2); /* di clock gate all */ + switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, VPU_CLK_GATE_OFF); +} + +void di_hw_uninit(void) +{ +} + +/* config di pre bit mode */ +static void pre_bit_mode_config(unsigned char inp, + unsigned char mem, unsigned char chan2, unsigned char nrwr) +{ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) + return; + + RDMA_WR_BITS(DI_INP_GEN_REG3, inp&0x3, 8, 2); + RDMA_WR_BITS(DI_MEM_GEN_REG3, mem&0x3, 8, 2); + RDMA_WR_BITS(DI_CHAN2_GEN_REG3, chan2&0x3, 8, 2); + RDMA_WR_BITS(DI_NRWR_Y, nrwr&0x1, 14, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL) && ((nrwr&0x3) == 0x3)) + RDMA_WR_BITS(DI_NRWR_CTRL, 0x3, 22, 2); +} + +unsigned int nr2_en = 0x1; +module_param(nr2_en, uint, 0644); +MODULE_PARM_DESC(nr2_en, "\n nr2_en\n"); + +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) +{ + int hist_check_only = 0; +#ifdef NEW_DI_V1 + int nr_w = 0, nr_h = 0; +#endif + pd32_check_en = 1; /* for progressive luma detection */ + + hist_check_only = hist_check_en && !nr_en && !mtn_en && + !pd22_check_en && !pd32_check_en; + + if (nr_en | mtn_en | pd22_check_en || pd32_check_en) { + set_di_mem_mif(di_mem_mif, urgent, hold_line); + if (!vdin_en) + set_di_inp_mif(di_inp_mif, urgent, hold_line); + } + + if (pd22_check_en || hist_check_only) { + set_di_chan2_mif(di_chan2_mif, urgent, hold_line); + #ifdef NEW_DI_V1 + RDMA_WR_BITS(DI_NR_CTRL0, cue_enable, 26, 1); + #endif + } else { + RDMA_WR_BITS(DI_NR_CTRL0, 0, 26, 1); + } + + /* set nr wr mif interface. */ + if (nr_en) { + RDMA_WR(DI_NRWR_X, (di_nrwr_mif->start_x << 16)| + (di_nrwr_mif->end_x)); + RDMA_WR_BITS(DI_NRWR_Y, di_nrwr_mif->start_y, 16, 13); + RDMA_WR_BITS(DI_NRWR_Y, di_nrwr_mif->end_y, 0, 13); + RDMA_WR_BITS(DI_NRWR_Y, 3, 30, 2); + RDMA_WR(DI_NRWR_CTRL, di_nrwr_mif->canvas_num| + (urgent<<16)| + 2<<26 |/*burst_lim 1->2 2->4*/ + 1<<30); /* urgent bit 16 */ + } + + pre_bit_mode_config(di_inp_mif->bit_mode, + di_mem_mif->bit_mode, + di_chan2_mif->bit_mode, + di_nrwr_mif->bit_mode); + /* motion wr mif. */ + if (mtn_en) { +#ifdef NEW_DI_V1 + RDMA_WR(DI_CONTWR_X, (di_contwr_mif->start_x << 16)| + (di_contwr_mif->end_x)); + RDMA_WR(DI_CONTWR_Y, (di_contwr_mif->start_y << 16)| + (di_contwr_mif->end_y)); + RDMA_WR(DI_CONTWR_CTRL, di_contwr_mif->canvas_num| + (urgent << 8));/* urgent. */ + RDMA_WR(DI_CONTPRD_X, (di_contprd_mif->start_x << 16)| + (di_contprd_mif->end_x)); + RDMA_WR(DI_CONTPRD_Y, (di_contprd_mif->start_y << 16)| + (di_contprd_mif->end_y)); + RDMA_WR(DI_CONTP2RD_X, (di_contp2rd_mif->start_x << 16)| + (di_contp2rd_mif->end_x)); + RDMA_WR(DI_CONTP2RD_Y, (di_contp2rd_mif->start_y << 16)| + (di_contp2rd_mif->end_y)); + RDMA_WR(DI_CONTRD_CTRL, (di_contprd_mif->canvas_num << 8)| + (urgent << 16)|/* urgent */ + di_contp2rd_mif->canvas_num); + /* current field mtn canvas index. */ +#endif + RDMA_WR(DI_MTNWR_X, (di_mtnwr_mif->start_x << 16)| + (di_mtnwr_mif->end_x)); + RDMA_WR(DI_MTNWR_Y, (di_mtnwr_mif->start_y << 16)| + (di_mtnwr_mif->end_y)); + RDMA_WR(DI_MTNWR_CTRL, di_mtnwr_mif->canvas_num| + (urgent << 8)); /* urgent. */ + RDMA_WR(DI_MTN_CTRL1, (0 << 8) | 2); + } + +#ifdef NEW_DI_V1 + nr_w = (di_nrwr_mif->end_x - di_nrwr_mif->start_x + 1); + nr_h = (di_nrwr_mif->end_y - di_nrwr_mif->start_y + 1); + RDMA_WR(NR2_FRM_SIZE, (nr_h<<16)|nr_w); + /*gate for nr*/ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) + RDMA_WR_BITS(NR2_SW_EN, nr2_en, 4, 1); + else { + /*only process sd,avoid affecting sharp*/ + if ((nr_h<<1) >= 720 || nr_w >= 1280) + RDMA_WR_BITS(NR2_SW_EN, 0, 4, 1); + else + RDMA_WR_BITS(NR2_SW_EN, nr2_en, 4, 1); + } + /*enable noise meter*/ + RDMA_WR_BITS(NR2_SW_EN, 1, 17, 1); +#endif + + /* frame + soft reset for the pre modules. */ + RDMA_WR(DI_PRE_CTRL, Rd(DI_PRE_CTRL) | 3 << 30); + + RDMA_WR(DI_PRE_CTRL, nr_en | /* NR enable */ + (mtn_en << 1) | /* MTN_EN */ + (pd32_check_en << 2)|/* check 3:2 pulldown */ + (pd22_check_en << 3)|/* check 2:2 pulldown */ + (1 << 4) | +/* 2:2 check mid pixel come from next field after MTN. */ + (hist_check_en << 5)|/* hist check enable */ + (1 << 6)|/* hist check use chan2. */ + ((!nr_en) << 7)| +/* hist check use data before noise reduction. */ + ((pd22_check_en || hist_check_only) << 8)| + /* chan 2 enable for 2:2 pull down check.*/ + (pd22_check_en << 9) |/* line buffer 2 enable */ + (0 << 10) | /* pre drop first. */ + (0 << 11) | /* di pre repeat */ + (0 << 12) | /* pre viu link */ + (pre_vdin_link << 13) | + (pre_vdin_link << 14) |/* pre go line link */ + (hold_line << 16)|/* pre hold line number */ + (1 << 22)|/* MTN after NR. */ + (pre_field_num << 29)|/* pre field number.*/ + (0x1 << 30) /* pre soft rst, pre frame rst */ + ); + +#ifdef SUPPORT_MPEG_TO_VDIN + if (mpeg2vdin_flag) + RDMA_WR_BITS(DI_PRE_CTRL, 1, 13, 1); +#endif +#ifdef DET3D + if (det3d_en && (!det3d_cfg)) { + det3d_enable(1); + det3d_cfg = 1; + } else if ((!det3d_en) && det3d_cfg) { + det3d_enable(0); + det3d_cfg = 0; + } +#endif +} +void enable_afbc_input(struct vframe_s *vf) +{ + unsigned int r, u, v; + + if (vf->type & VIDTYPE_COMPRESS) { + r = (3 << 24) | + (17 << 16) | + (1 << 14) | /*burst1 1*/ + vf->bitdepth; + + if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) + r |= 0x44; + else if ((vf->type & VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_BOTTOM) + r |= 0x88; + + RDMA_WR(AFBC_MODE, r); + RDMA_WR(AFBC_ENABLE, 0x1700); + RDMA_WR(AFBC_CONV_CTRL, 0x100); + u = (vf->bitdepth >> (BITDEPTH_U_SHIFT)) & 0x3; + v = (vf->bitdepth >> (BITDEPTH_V_SHIFT)) & 0x3; + RDMA_WR(AFBC_DEC_DEF_COLOR, + 0x3FF00000 | /*Y,bit20+*/ + 0x80 << (u + 10) | + 0x80 << v); + /* chroma formatter */ + RDMA_WR(AFBC_VD_CFMT_CTRL, + (1<<21)|/* HFORMATTER_YC_RATIO_2_1 */ + (1<<20)|/* HFORMATTER_EN */ + (1<<16)|/* VFORMATTER_RPTLINE0_EN */ + (0x8 << 1)|/* VFORMATTER_PHASE_BIT */ + 1);/* VFORMATTER_EN */ + + RDMA_WR(AFBC_VD_CFMT_W, + (vf->width << 16) | (vf->width/2)); + + RDMA_WR(AFBC_MIF_HOR_SCOPE, + (0 << 16) | ((vf->width - 1)>>5)); + + RDMA_WR(AFBC_PIXEL_HOR_SCOPE, + (0 << 16) | (vf->width - 1)); + RDMA_WR(AFBC_VD_CFMT_H, vf->height); + + RDMA_WR(AFBC_MIF_VER_SCOPE, + (0 << 16) | ((vf->height-1)>>2)); + + RDMA_WR(AFBC_PIXEL_VER_SCOPE, + 0 << 16 | (vf->height-1)); + RDMA_WR(AFBC_SIZE_IN, vf->height | vf->width << 16); + RDMA_WR(AFBC_HEAD_BADDR, vf->canvas0Addr>>4); + RDMA_WR(AFBC_BODY_BADDR, vf->canvas1Addr>>4); + /* disable inp memory */ + RDMA_WR_BITS(DI_INP_GEN_REG, 0, 0, 1); + /* afbc to di enable */ + if (Rd_reg_bits(VIU_MISC_CTRL0, 19, 1) != 1) + RDMA_WR_BITS(VIU_MISC_CTRL0, 1, 19, 1); + /* DI inp(current data) switch to AFBC */ + RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1); + } else { + RDMA_WR(AFBC_ENABLE, 0); + /* afbc to vpp(replace vd1) enable */ + if (Rd_reg_bits(VIU_MISC_CTRL0, 19, 1) != 0) + RDMA_WR_BITS(VIU_MISC_CTRL0, 0, 19, 1); + /* DI inp(current data) switch to memory */ + RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1); + } +} + +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) +{ + RDMA_WR(MCDI_MCVECWR_X, di_mcvecwr_mif->size_x); + RDMA_WR(MCDI_MCVECWR_Y, di_mcvecwr_mif->size_y); + RDMA_WR(MCDI_MCINFOWR_X, di_mcinfowr_mif->size_x); + RDMA_WR(MCDI_MCINFOWR_Y, di_mcinfowr_mif->size_y); + + RDMA_WR(MCDI_MCINFORD_X, di_mcinford_mif->size_x); + RDMA_WR(MCDI_MCINFORD_Y, di_mcinford_mif->size_y); + RDMA_WR(MCDI_MCVECWR_CANVAS_SIZE, + (di_mcvecwr_mif->size_x<<16)+di_mcvecwr_mif->size_y); + RDMA_WR(MCDI_MCINFOWR_CANVAS_SIZE, + (di_mcinfowr_mif->size_x<<16)+di_mcinfowr_mif->size_y); + RDMA_WR(MCDI_MCINFORD_CANVAS_SIZE, + (di_mcinford_mif->size_x<<16)+di_mcinford_mif->size_y); + + /* DI_Wr(MCDI_MOTINEN,1<<1); //enable motin refinement */ + + RDMA_WR(MCDI_MCVECWR_CTRL, di_mcvecwr_mif->canvas_num | + (0<<14) | /* sync latch en */ + (urgent<<8) | /* urgent */ + (1<<12) | /* enable reset by frame rst */ + (0x4031<<16)); + RDMA_WR(MCDI_MCINFOWR_CTRL, di_mcinfowr_mif->canvas_num | + (0<<14) | /* sync latch en */ + (urgent<<8) | /* urgent */ + (1<<12) | /* enable reset by frame rst */ + (0x4042<<16)); + RDMA_WR(MCDI_MCINFORD_CTRL, di_mcinford_mif->canvas_num | + (0<<10) | /* sync latch en */ + (urgent<<8) | /* urgent */ + (1<<9) | /* enable reset by frame rst */ + (0x42<<16)); +} + +void enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif, + int urgent, bool reverse) +{ + DI_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_X, (reverse?1:0)<<30 | + di_mcvecrd_mif->start_x<<16 | + (di_mcvecrd_mif->size_x+di_mcvecrd_mif->start_x)); + DI_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_Y, (reverse?1:0)<<30 | + di_mcvecrd_mif->start_y<<16 | + (di_mcvecrd_mif->size_y+di_mcvecrd_mif->start_y)); + DI_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_CANVAS_SIZE, + (di_mcvecrd_mif->size_x<<16)+di_mcvecrd_mif->size_y); + DI_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_CTRL, di_mcvecrd_mif->canvas_num | + (urgent<<8)|/* urgent */ + (1<<9)|/* canvas enable */ + (0 << 10) | + (0x31<<16)); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, di_mcvecrd_mif->vecrd_offset, + 12, 3); + + if (di_mcvecrd_mif->blend_mode == 3) + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcen_mode, 0, 2); + else + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + if (is_meson_txl_cpu()) { + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcuv_en, 10, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 3); + } else + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcuv_en, 9, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcdebug_mode, 2, 3); +} + + + +static void set_di_inp_fmt_more(unsigned int repeat_l0_en, + int hz_yc_ratio, /* 2bit */ + int hz_ini_phase, /* 4bit */ + int vfmt_en, + int vt_yc_ratio, /* 2bit */ + int vt_ini_phase, /* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ) +{ + int hfmt_en = 1, nrpt_phase0_en = 0; + int vt_phase_step = (16 >> vt_yc_ratio); + + RDMA_WR(DI_INP_FMT_CTRL, (hz_rpt << 28) |/* hz rpt pixel */ + (hz_ini_phase << 24) |/* hz ini phase */ + (0 << 23) |/* repeat p0 enable */ + (hz_yc_ratio << 21) |/* hz yc ratio */ + (hfmt_en << 20) |/* hz enable */ + (nrpt_phase0_en << 17)|/* nrpt_phase0 enable */ + (repeat_l0_en << 16)|/* repeat l0 enable */ + (0 << 12) |/* skip line num */ + (vt_ini_phase << 8) |/* vt ini phase */ + (vt_phase_step << 1)|/* vt phase step (3.4) */ + (vfmt_en << 0) /* vt enable */ + ); + + RDMA_WR(DI_INP_FMT_W, (y_length << 16) | /* hz format width */ + (c_length << 0)/* vt format width */ + ); +} + +static void set_di_inp_mif(struct DI_MIF_s *mif, int urgent, int hold_line) +{ + unsigned int bytes_per_pixel; + unsigned int demux_mode; + unsigned int chro_rpt_lastl_ctrl, vfmt_rpt_first = 0; + unsigned int luma0_rpt_loop_start; + unsigned int luma0_rpt_loop_end; + unsigned int luma0_rpt_loop_pat; + unsigned int chroma0_rpt_loop_start; + unsigned int chroma0_rpt_loop_end; + unsigned int chroma0_rpt_loop_pat; + unsigned int vt_ini_phase = 0; + unsigned int reset_on_gofield; + + if (mif->set_separate_en != 0 && mif->src_field_mode == 1) { + chro_rpt_lastl_ctrl = 1; + luma0_rpt_loop_start = 1; + luma0_rpt_loop_end = 1; + chroma0_rpt_loop_start = mif->src_prog?0:1; + chroma0_rpt_loop_end = mif->src_prog?0:1; + luma0_rpt_loop_pat = 0x80; + chroma0_rpt_loop_pat = mif->src_prog?0:0x80; + + vfmt_rpt_first = 1; + if (mif->output_field_num == 0) + vt_ini_phase = 0xe; + else + vt_ini_phase = 0xa; + + if (mif->src_prog) { + if (mif->output_field_num == 0) { + vt_ini_phase = 0xc; + } else { + vt_ini_phase = 0x4; + vfmt_rpt_first = 0; + } + } + + } else if (mif->set_separate_en != 0 && mif->src_field_mode == 0) { + chro_rpt_lastl_ctrl = 1; + luma0_rpt_loop_start = 0; + luma0_rpt_loop_end = 0; + chroma0_rpt_loop_start = 0; + chroma0_rpt_loop_end = 0; + luma0_rpt_loop_pat = 0x0; + chroma0_rpt_loop_pat = 0x0; + } else if (mif->set_separate_en == 0 && mif->src_field_mode == 1) { + chro_rpt_lastl_ctrl = 1; + luma0_rpt_loop_start = 1; + luma0_rpt_loop_end = 1; + chroma0_rpt_loop_start = 1; + chroma0_rpt_loop_end = 1; + luma0_rpt_loop_pat = 0x80; + chroma0_rpt_loop_pat = 0x80; + } else { + chro_rpt_lastl_ctrl = 0; + luma0_rpt_loop_start = 0; + luma0_rpt_loop_end = 0; + chroma0_rpt_loop_start = 0; + chroma0_rpt_loop_end = 0; + luma0_rpt_loop_pat = 0x00; + chroma0_rpt_loop_pat = 0x00; + } + + + bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + demux_mode = mif->video_mode; + + + /* ---------------------- */ + /* General register */ + /* ---------------------- */ + reset_on_gofield = (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)?0:1; + RDMA_WR(DI_INP_GEN_REG, (reset_on_gofield << 29) | + (urgent << 28) |/* chroma urgent bit */ + (urgent << 27) |/* luma urgent bit. */ + (1 << 25) |/* no dummy data. */ + (hold_line << 19) |/* hold lines */ + (1 << 18) |/* push dummy pixel */ + (demux_mode << 16) |/* demux_mode */ + (bytes_per_pixel << 14) | + (1 << 12) |/*burst_size_cr*/ + (1 << 10) |/*burst_size_cb*/ + (3 << 8) |/*burst_size_y*/ + (chro_rpt_lastl_ctrl << 6) | + ((mif->set_separate_en != 0) << 1) | + (0 << 0)/* cntl_enable */ + ); + if (mif->set_separate_en == 2) { + /* Enable NV12 Display */ + RDMA_WR_BITS(DI_INP_GEN_REG2, 1, 0, 1); + } else { + RDMA_WR_BITS(DI_INP_GEN_REG2, 0, 0, 1); + } + + RDMA_WR(DI_INP_CANVAS0, (mif->canvas0_addr2 << 16) | + /* cntl_canvas0_addr2 */ + (mif->canvas0_addr1 << 8) | + /* cntl_canvas0_addr1 */ + (mif->canvas0_addr0 << 0) + /* cntl_canvas0_addr0 */ + ); + + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + RDMA_WR(DI_INP_LUMA_X0, (mif->luma_x_end0 << 16) | + /* cntl_luma_x_end0 */ + (mif->luma_x_start0 << 0)/* cntl_luma_x_start0 */ + ); + RDMA_WR(DI_INP_LUMA_Y0, (mif->luma_y_end0 << 16) | + /* cntl_luma_y_end0 */ + (mif->luma_y_start0 << 0) /* cntl_luma_y_start0 */ + ); + RDMA_WR(DI_INP_CHROMA_X0, (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0) + ); + RDMA_WR(DI_INP_CHROMA_Y0, (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0) + ); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + RDMA_WR(DI_INP_RPT_LOOP, (0 << 28) | + (0 << 24) | + (0 << 20) | + (0 << 16) | + (chroma0_rpt_loop_start << 12) | + (chroma0_rpt_loop_end << 8) | + (luma0_rpt_loop_start << 4) | + (luma0_rpt_loop_end << 0) + ); + + RDMA_WR(DI_INP_LUMA0_RPT_PAT, luma0_rpt_loop_pat); + RDMA_WR(DI_INP_CHROMA0_RPT_PAT, chroma0_rpt_loop_pat); + + /* Dummy pixel value */ + RDMA_WR(DI_INP_DUMMY_PIXEL, 0x00808000); + if ((mif->set_separate_en != 0)) {/* 4:2:0 block mode.*/ + set_di_inp_fmt_more( + vfmt_rpt_first,/* hfmt_en */ + 1,/* hz_yc_ratio */ + 0,/* hz_ini_phase */ + 1,/* vfmt_en */ + mif->src_prog?0:1,/* vt_yc_ratio */ + vt_ini_phase,/* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + /* y_length */ + mif->chroma_x_end0 - mif->chroma_x_start0 + 1, + /* c length */ + 0); /* hz repeat. */ + } else { + set_di_inp_fmt_more( + vfmt_rpt_first, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 0, /* vfmt_en */ + 0, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + ((mif->luma_x_end0 >> 1) - (mif->luma_x_start0>>1) + 1), + 0); /* hz repeat. */ + } +} + +static void set_di_mem_fmt_more(int hfmt_en, + int hz_yc_ratio, /* 2bit */ + int hz_ini_phase, /* 4bit */ + int vfmt_en, + int vt_yc_ratio, /* 2bit */ + int vt_ini_phase, /* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ) +{ + int vt_phase_step = (16 >> vt_yc_ratio); + + RDMA_WR(DI_MEM_FMT_CTRL, + (hz_rpt << 28) | /* hz rpt pixel */ + (hz_ini_phase << 24) | /* hz ini phase */ + (0 << 23) | /* repeat p0 enable */ + (hz_yc_ratio << 21) | /* hz yc ratio */ + (hfmt_en << 20) | /* hz enable */ + (1 << 17) | /* nrpt_phase0 enable */ + (0 << 16) | /* repeat l0 enable */ + (0 << 12) | /* skip line num */ + (vt_ini_phase << 8) | /* vt ini phase */ + (vt_phase_step << 1) | /* vt phase step (3.4) */ + (vfmt_en << 0) /* vt enable */ + ); + + RDMA_WR(DI_MEM_FMT_W, (y_length << 16) | /* hz format width */ + (c_length << 0) /* vt format width */ + ); +} + +#ifdef NEW_DI_V1 +static void set_di_chan2_fmt_more(int hfmt_en, + int hz_yc_ratio,/* 2bit */ + int hz_ini_phase,/* 4bit */ + int vfmt_en, + int vt_yc_ratio,/* 2bit */ + int vt_ini_phase,/* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ) +{ + int vt_phase_step = (16 >> vt_yc_ratio); + + RDMA_WR(DI_CHAN2_FMT_CTRL, (hz_rpt << 28) | /* hz rpt pixel */ + (hz_ini_phase << 24) | /* hz ini phase */ + (0 << 23) | /* repeat p0 enable */ + (hz_yc_ratio << 21) | /* hz yc ratio */ + (hfmt_en << 20) | /* hz enable */ + (1 << 17) | /* nrpt_phase0 enable */ + (0 << 16) | /* repeat l0 enable */ + (0 << 12) | /* skip line num */ + (vt_ini_phase << 8) | /* vt ini phase */ + (vt_phase_step << 1) | /* vt phase step (3.4) */ + (vfmt_en << 0) /* vt enable */ + ); + + RDMA_WR(DI_CHAN2_FMT_W, (y_length << 16) | /* hz format width */ + (c_length << 0) /* vt format width */ + ); +} +#endif + +static void set_di_mem_mif(struct DI_MIF_s *mif, int urgent, int hold_line) +{ + unsigned int bytes_per_pixel; + unsigned int demux_mode; + unsigned int chro_rpt_lastl_ctrl; + unsigned int luma0_rpt_loop_start; + unsigned int luma0_rpt_loop_end; + unsigned int luma0_rpt_loop_pat; + unsigned int chroma0_rpt_loop_start; + unsigned int chroma0_rpt_loop_end; + unsigned int chroma0_rpt_loop_pat; + unsigned int reset_on_gofield; + + if (mif->set_separate_en != 0 && mif->src_field_mode == 1) { + chro_rpt_lastl_ctrl = 1; + luma0_rpt_loop_start = 1; + luma0_rpt_loop_end = 1; + chroma0_rpt_loop_start = 1; + chroma0_rpt_loop_end = 1; + luma0_rpt_loop_pat = 0x80; + chroma0_rpt_loop_pat = 0x80; + } else if (mif->set_separate_en != 0 && mif->src_field_mode == 0) { + chro_rpt_lastl_ctrl = 1; + luma0_rpt_loop_start = 0; + luma0_rpt_loop_end = 0; + chroma0_rpt_loop_start = 0; + chroma0_rpt_loop_end = 0; + luma0_rpt_loop_pat = 0x0; + chroma0_rpt_loop_pat = 0x0; + } else if (mif->set_separate_en == 0 && mif->src_field_mode == 1) { + chro_rpt_lastl_ctrl = 1; + luma0_rpt_loop_start = 1; + luma0_rpt_loop_end = 1; + chroma0_rpt_loop_start = 0; + chroma0_rpt_loop_end = 0; + luma0_rpt_loop_pat = 0x80; + chroma0_rpt_loop_pat = 0x00; + } else { + chro_rpt_lastl_ctrl = 0; + luma0_rpt_loop_start = 0; + luma0_rpt_loop_end = 0; + chroma0_rpt_loop_start = 0; + chroma0_rpt_loop_end = 0; + luma0_rpt_loop_pat = 0x00; + chroma0_rpt_loop_pat = 0x00; + } + + bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + demux_mode = mif->video_mode; + + + /* ---------------------- */ + /* General register */ + /* ---------------------- */ + reset_on_gofield = (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)?0:1; + RDMA_WR(DI_MEM_GEN_REG, (reset_on_gofield << 29) | + /* reset on go field */ + (urgent << 28) | /* urgent bit. */ + (urgent << 27) | /* urgent bit. */ + (1 << 25) | /* no dummy data. */ + (hold_line << 19) | /* hold lines */ + (1 << 18) | /* push dummy pixel */ + (demux_mode << 16) | /* demux_mode */ + (bytes_per_pixel << 14) | + (1 << 12) |/*burst_size_cr*/ + (1 << 10) |/*burst_size_cb*/ + (3 << 8) |/*burst_size_y*/ + (chro_rpt_lastl_ctrl << 6) | + ((mif->set_separate_en != 0) << 1)| + (0 << 0) /* cntl_enable */ + ); + if (mif->set_separate_en == 2) { + /* Enable NV12 Display */ + RDMA_WR_BITS(DI_MEM_GEN_REG2, 1, 0, 1); + } else { + RDMA_WR_BITS(DI_MEM_GEN_REG2, 0, 0, 1); + } + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + RDMA_WR(DI_MEM_CANVAS0, (mif->canvas0_addr2 << 16) | + /* cntl_canvas0_addr2 */ +(mif->canvas0_addr1 << 8) | (mif->canvas0_addr0 << 0)); + + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + RDMA_WR(DI_MEM_LUMA_X0, (mif->luma_x_end0 << 16) | +(mif->luma_x_start0 << 0) /* cntl_luma_x_start0 */ + ); + RDMA_WR(DI_MEM_LUMA_Y0, (mif->luma_y_end0 << 16) | +(mif->luma_y_start0 << 0) /* cntl_luma_y_start0 */ + ); + RDMA_WR(DI_MEM_CHROMA_X0, (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0) + ); + RDMA_WR(DI_MEM_CHROMA_Y0, (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0) + ); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + RDMA_WR(DI_MEM_RPT_LOOP, (0 << 28) | + (0 << 24) | + (0 << 20) | + (0 << 16) | + (chroma0_rpt_loop_start << 12) | + (chroma0_rpt_loop_end << 8) | + (luma0_rpt_loop_start << 4) | + (luma0_rpt_loop_end << 0) + ); + + RDMA_WR(DI_MEM_LUMA0_RPT_PAT, luma0_rpt_loop_pat); + RDMA_WR(DI_MEM_CHROMA0_RPT_PAT, chroma0_rpt_loop_pat); + + /* Dummy pixel value */ + RDMA_WR(DI_MEM_DUMMY_PIXEL, 0x00808000); + if ((mif->set_separate_en != 0)) {/* 4:2:0 block mode.*/ + set_di_mem_fmt_more( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 1, /* vfmt_en */ + 1, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + /* y_length */ + mif->chroma_x_end0 - mif->chroma_x_start0 + 1, + /* c length */ + 0); /* hz repeat. */ + } else { + set_di_mem_fmt_more(1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 0, /* vfmt_en */ + 0, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + ((mif->luma_x_end0 >> 1) - (mif->luma_x_start0>>1) + 1), + 0); /* hz repeat. */ + } +} + +static void set_di_if0_fmt_more(int hfmt_en, + int hz_yc_ratio, /* 2bit */ + int hz_ini_phase, /* 4bit */ + int vfmt_en, + int vt_yc_ratio, /* 2bit */ + int vt_ini_phase, /* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ) +{ + int vt_phase_step = (16 >> vt_yc_ratio); + + DI_VSYNC_WR_MPEG_REG(VIU_VD1_FMT_CTRL, +(hz_rpt << 28) | /* hz rpt pixel */ +(hz_ini_phase << 24) | /* hz ini phase */ +(0 << 23) | /* repeat p0 enable */ +(hz_yc_ratio << 21) | /* hz yc ratio */ +(hfmt_en << 20) | /* hz enable */ +(1 << 17) | /* nrpt_phase0 enable */ +(0 << 16) | /* repeat l0 enable */ +(0 << 12) | /* skip line num */ +(vt_ini_phase << 8) | /* vt ini phase */ +(vt_phase_step << 1) | /* vt phase step (3.4) */ +(vfmt_en << 0) /* vt enable */ + ); + + DI_VSYNC_WR_MPEG_REG(VIU_VD1_FMT_W, + (y_length << 16) | /* hz format width */ + (c_length << 0) /* vt format width */ + ); +} + +static void set_di_if1_fmt_more(int hfmt_en, + int hz_yc_ratio,/* 2bit */ + int hz_ini_phase,/* 4bit */ + int vfmt_en, + int vt_yc_ratio,/* 2bit */ + int vt_ini_phase,/* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ) +{ + int vt_phase_step = (16 >> vt_yc_ratio); + + DI_VSYNC_WR_MPEG_REG(DI_IF1_FMT_CTRL, + (hz_rpt << 28)|/* hz rpt pixel */ + (hz_ini_phase << 24)|/* hz ini phase */ + (0 << 23)|/* repeat p0 enable */ + (hz_yc_ratio << 21)|/* hz yc ratio */ + (hfmt_en << 20)|/* hz enable */ + (1 << 17)|/* nrpt_phase0 enable */ + (0 << 16)|/* repeat l0 enable */ + (0 << 12)|/* skip line num */ + (vt_ini_phase << 8)|/* vt ini phase */ + (vt_phase_step << 1)|/* vt phase step (3.4) */ + (vfmt_en << 0) /* vt enable */ + ); + + DI_VSYNC_WR_MPEG_REG(DI_IF1_FMT_W, (y_length << 16) | + (c_length << 0)); +} +static void set_di_if2_fmt_more(int hfmt_en, + int hz_yc_ratio,/* 2bit */ + int hz_ini_phase,/* 4bit */ + int vfmt_en, + int vt_yc_ratio,/* 2bit */ + int vt_ini_phase,/* 4bit */ + int y_length, + int c_length, + int hz_rpt /* 1bit */ + ) +{ + int vt_phase_step = (16 >> vt_yc_ratio); + + DI_VSYNC_WR_MPEG_REG(DI_IF2_FMT_CTRL, + (hz_rpt << 28)|/* hz rpt pixel */ + (hz_ini_phase << 24)|/* hz ini phase */ + (0 << 23)|/* repeat p0 enable */ + (hz_yc_ratio << 21)|/* hz yc ratio */ + (hfmt_en << 20)|/* hz enable */ + (1 << 17)|/* nrpt_phase0 enable */ + (0 << 16)|/* repeat l0 enable */ + (0 << 12)|/* skip line num */ + (vt_ini_phase << 8)|/* vt ini phase */ + (vt_phase_step << 1)|/* vt phase step (3.4) */ + (vfmt_en << 0) /* vt enable */ + ); + + DI_VSYNC_WR_MPEG_REG(DI_IF2_FMT_W, (y_length << 16) | + (c_length << 0)); +} + +static const u32 vpat[] = {0, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}; + +static void set_di_if2_mif(struct DI_MIF_s *mif, int urgent, int hold_line) +{ + unsigned int bytes_per_pixel, demux_mode; + unsigned int pat, loop = 0, chro_rpt_lastl_ctrl = 0; + + if (mif->set_separate_en == 1) { + pat = vpat[(di_vscale_skip_count_real<<1)+1]; + /*top*/ + if (mif->src_field_mode == 0) { + chro_rpt_lastl_ctrl = 1; + loop = 0x11; + pat <<= 4; + } + } else { + loop = 0; + pat = vpat[di_vscale_skip_count_real]; + } + + bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + demux_mode = mif->video_mode; + + + /* ---------------------- */ + /* General register */ + /* ---------------------- */ + + DI_VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG, (0 << 29) | /* reset on go field */ + (urgent << 28) |/* urgent */ + (urgent << 27) |/* luma urgent */ + (1 << 25)|/* no dummy data. */ + (hold_line << 19)|/* hold lines */ + (1 << 18)|/* push dummy pixel */ + (demux_mode << 16)|/* demux_mode */ + (bytes_per_pixel << 14)| + (1 << 12)|/*burst_size_cr*/ + (1 << 10)|/*burst_size_cb*/ + (3 << 8)|/*burst_size_y*/ + (chro_rpt_lastl_ctrl << 6)| + ((mif->set_separate_en != 0) << 1)| + (1 << 0)/* cntl_enable */ + ); + /* post bit mode config, if0 config in video.c + * DI_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG3, mif->bit_mode, 8, 2); + */ + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF2_CANVAS0, (mif->canvas0_addr2 << 16) | + (mif->canvas0_addr1 << 8) | (mif->canvas0_addr0 << 0)); + + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF2_LUMA_X0, (mif->luma_x_end0 << 16) | + (mif->luma_x_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF2_LUMA_Y0, (mif->luma_y_end0 << 16) | + (mif->luma_y_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA_X0, (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA_Y0, (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0)); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF2_RPT_LOOP, (loop << 24) | + (loop << 16) | + (loop << 8) | + (loop << 0) + ); + + DI_VSYNC_WR_MPEG_REG(DI_IF2_LUMA0_RPT_PAT, pat); + DI_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA0_RPT_PAT, pat); + + /* Dummy pixel value */ + DI_VSYNC_WR_MPEG_REG(DI_IF2_DUMMY_PIXEL, 0x00808000); + if (mif->set_separate_en != 0) { /* 4:2:0 block mode. */ + set_di_if2_fmt_more(1, /* hfmt_en */ + 1,/* hz_yc_ratio */ + 0,/* hz_ini_phase */ + 1, /* vfmt_en */ + 1, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + mif->chroma_x_end0 - mif->chroma_x_start0 + 1, + 0); /* hz repeat. */ + } else { + set_di_if2_fmt_more(1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 0, /* vfmt_en */ + 0, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + ((mif->luma_x_end0 >> 1) - (mif->luma_x_start0>>1) + 1), + 0); /* hz repeat */ + } +} + +static void set_di_if1_mif(struct DI_MIF_s *mif, int urgent, int hold_line) +{ + unsigned int bytes_per_pixel, demux_mode; + unsigned int pat, loop = 0, chro_rpt_lastl_ctrl = 0; + + if (mif->set_separate_en == 1) { + pat = vpat[(di_vscale_skip_count_real<<1)+1]; + /*top*/ + if (mif->src_field_mode == 0) { + chro_rpt_lastl_ctrl = 1; + loop = 0x11; + pat <<= 4; + } + } else { + loop = 0; + pat = vpat[di_vscale_skip_count_real]; + } + + bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + demux_mode = mif->video_mode; + + + /* ---------------------- */ + /* General register */ + /* ---------------------- */ + + DI_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, (0 << 29) | /* reset on go field */ + (urgent << 28) |/* urgent */ + (urgent << 27) |/* luma urgent */ + (1 << 25)|/* no dummy data. */ + (hold_line << 19)|/* hold lines */ + (1 << 18)|/* push dummy pixel */ + (demux_mode << 16)|/* demux_mode */ + (bytes_per_pixel << 14)| + (1 << 12)|/*burst_size_cr*/ + (1 << 10)|/*burst_size_cb*/ + (3 << 8)|/*burst_size_y*/ + (chro_rpt_lastl_ctrl << 6)| + ((mif->set_separate_en != 0) << 1)| + (1 << 0)/* cntl_enable */ + ); + #if 0 + /* post bit mode config, if0 config in video.c */ + if (is_meson_gxtvbb_cpu() || is_meson_gxl_cpu() || is_meson_gxm_cpu()) + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG3, mif->bit_mode, 8, 2); + #endif + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF1_CANVAS0, (mif->canvas0_addr2 << 16) | +(mif->canvas0_addr1 << 8) | (mif->canvas0_addr0 << 0)); + + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF1_LUMA_X0, (mif->luma_x_end0 << 16) | +(mif->luma_x_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF1_LUMA_Y0, (mif->luma_y_end0 << 16) | +(mif->luma_y_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA_X0, (mif->chroma_x_end0 << 16) | +(mif->chroma_x_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA_Y0, (mif->chroma_y_end0 << 16) | +(mif->chroma_y_start0 << 0)); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(DI_IF1_RPT_LOOP, (loop << 24) | + (loop << 16) | + (loop << 8) | + (loop << 0) + ); + + DI_VSYNC_WR_MPEG_REG(DI_IF1_LUMA0_RPT_PAT, pat); + DI_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA0_RPT_PAT, pat); + + /* Dummy pixel value */ + DI_VSYNC_WR_MPEG_REG(DI_IF1_DUMMY_PIXEL, 0x00808000); + if (mif->set_separate_en != 0) { /* 4:2:0 block mode. */ + set_di_if1_fmt_more(1, /* hfmt_en */ + 1,/* hz_yc_ratio */ + 0,/* hz_ini_phase */ + 1, /* vfmt_en */ + 1, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + mif->chroma_x_end0 - mif->chroma_x_start0 + 1, + 0); /* hz repeat. */ + } else { + set_di_if1_fmt_more(1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 0, /* vfmt_en */ + 0, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + ((mif->luma_x_end0 >> 1) - (mif->luma_x_start0>>1) + 1), + 0); /* hz repeat */ + } +} + +static void set_di_chan2_mif(struct DI_MIF_s *mif, int urgent, int hold_line) +{ + unsigned int bytes_per_pixel; + unsigned int demux_mode; + unsigned int luma0_rpt_loop_start; + unsigned int luma0_rpt_loop_end; + unsigned int luma0_rpt_loop_pat; + unsigned int reset_on_gofield; + + bytes_per_pixel = mif->set_separate_en ? 0 : +((mif->video_mode == 1) ? 2 : 1); + demux_mode = mif->video_mode & 1; + + if (mif->src_field_mode == 1) { + luma0_rpt_loop_start = 1; + luma0_rpt_loop_end = 1; + luma0_rpt_loop_pat = 0x80; + } else { + luma0_rpt_loop_start = 0; + luma0_rpt_loop_end = 0; + luma0_rpt_loop_pat = 0; + } + /* ---------------------- */ + /* General register */ + /* ---------------------- */ + reset_on_gofield = (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB)?0:1; + RDMA_WR(DI_CHAN2_GEN_REG, (reset_on_gofield << 29) | + (urgent << 28) | /* urgent */ + (urgent << 27) | /* luma urgent */ + (1 << 25) | /* no dummy data. */ + (hold_line << 19) | /* hold lines */ + (1 << 18) |/* push dummy pixel */ + (demux_mode << 16) | + (bytes_per_pixel << 14) | + (1 << 12) |/*burst_size_cr*/ + (1 << 10) |/*burst_size_cb*/ + (3 << 8) |/*burst_size_y*/ +((hold_line == 0 ? 1 : 0) << 7) | +(0 << 6)|(0 << 1)|(0 << 0)); + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + if (mif->set_separate_en == 2) { + /* Enable NV12 Display */ + RDMA_WR_BITS(DI_CHAN2_GEN_REG2, 1, 0, 1); + } else { + RDMA_WR_BITS(DI_CHAN2_GEN_REG2, 0, 0, 1); + } + RDMA_WR(DI_CHAN2_CANVAS, (0 << 16) | /* cntl_canvas0_addr2 */ +(0 << 8)|(mif->canvas0_addr0 << 0)); + + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + RDMA_WR(DI_CHAN2_LUMA_X, (mif->luma_x_end0 << 16) | + /* cntl_luma_x_end0 */ +(mif->luma_x_start0 << 0)); + RDMA_WR(DI_CHAN2_LUMA_Y, (mif->luma_y_end0 << 16) | + /* cntl_luma_y_end0 */ +(mif->luma_y_start0 << 0)); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + RDMA_WR(DI_CHAN2_RPT_LOOP, (0 << 28) | + (0 << 24) | + (0 << 20) | + (0 << 16) | + (0 << 12) | + (0 << 8) | + (luma0_rpt_loop_start << 4) | + (luma0_rpt_loop_end << 0) + ); + + RDMA_WR(DI_CHAN2_LUMA_RPT_PAT, luma0_rpt_loop_pat); + + /* Dummy pixel value */ + RDMA_WR(DI_CHAN2_DUMMY_PIXEL, 0x00808000); + +#ifdef NEW_DI_V1 + if ((mif->set_separate_en != 0)) { /* 4:2:0 block mode. */ + set_di_chan2_fmt_more( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 1, /* vfmt_en */ + 1, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, /* y_length */ + mif->chroma_x_end0 - mif->chroma_x_start0 + 1,/* c length */ + 0); /* hz repeat. */ + } else { + set_di_chan2_fmt_more( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 0, /* vfmt_en */ + 0, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, /* y_length */ + ((mif->luma_x_end0 >> 1) - (mif->luma_x_start0>>1) + 1), + 0); /* hz repeat. */ + } +#endif + +} + +static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent, int hold_line) +{ + unsigned int pat, loop = 0; + unsigned int bytes_per_pixel, demux_mode; + + if (mif->set_separate_en == 1) { + pat = vpat[(di_vscale_skip_count_real<<1)+1]; + if (mif->src_field_mode == 0) {/* top */ + loop = 0x11; + pat <<= 4; + } + } else { + loop = 0; + pat = vpat[di_vscale_skip_count_real]; + + if ((post_wr_en && post_wr_surpport)) { + bytes_per_pixel = + mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + demux_mode = mif->video_mode; + DI_VSYNC_WR_MPEG_REG(VD1_IF0_GEN_REG, +(0 << 29) | /* reset on go field */ +(urgent << 28) | /* urgent */ +(urgent << 27) | /* luma urgent */ +(1 << 25) | /* no dummy data. */ +(hold_line << 19) | /* hold lines */ +(1 << 18) | /* push dummy pixel */ +(demux_mode << 16) | /* demux_mode */ +(bytes_per_pixel << 14) | +(1 << 12) | +(1 << 10) | +(3 << 8) | +(0 << 6) | +((mif->set_separate_en != 0) << 1) | +(1 << 0) /* cntl_enable */ + ); + } + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(VD1_IF0_CANVAS0, (mif->canvas0_addr2 << 16)| +(mif->canvas0_addr1 << 8)|(mif->canvas0_addr0 << 0)); + + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_X0, (mif->luma_x_end0 << 16) | +(mif->luma_x_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_Y0, (mif->luma_y_end0 << 16) | +(mif->luma_y_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_X0, (mif->chroma_x_end0 << 16) | +(mif->chroma_x_start0 << 0)); + DI_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_Y0, (mif->chroma_y_end0 << 16) | +(mif->chroma_y_start0 << 0)); + + } + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + DI_VSYNC_WR_MPEG_REG(VD1_IF0_RPT_LOOP, + (loop << 24) | + (loop << 16) | + (loop << 8) | + (loop << 0)); + DI_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA0_RPT_PAT, pat); + DI_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA0_RPT_PAT, pat); + + if ((post_wr_en && post_wr_surpport)) { + /* 4:2:0 block mode. */ + if (mif->set_separate_en != 0) { + set_di_if0_fmt_more( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 1, /* vfmt_en */ + 1, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ +mif->luma_x_end0 - mif->luma_x_start0 + 1, /* y_length */ +mif->chroma_x_end0 - mif->chroma_x_start0 + 1, /* c length */ + 0); /* hz repeat. */ + } else { + set_di_if0_fmt_more( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 0, /* vfmt_en */ + 0, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, /* y_length */ + ((mif->luma_x_end0>>1) - (mif->luma_x_start0>>1) + 1), /* c length */ + 0); /* hz repeat */ + } + } +} + +void initial_di_pre_aml(int hsize_pre, int vsize_pre, int hold_line) +{ + DI_Wr(DI_PRE_SIZE, (hsize_pre - 1) | ((vsize_pre - 1) << 16)); + DI_Wr(DI_PRE_CTRL, 0 | /* NR enable */ +(0 << 1) | /* MTN_EN */ +(1 << 2) | /* check 3:2 pulldown */ +(0 << 3) | /* check 2:2 pulldown */ +(0 << 4) | /* 2:2 check mid pixel come from next field after MTN. */ +(0 << 5) | /* hist check enable */ +(0 << 6) | /* hist check not use chan2. */ +(0 << 7) | /* hist check use data before noise reduction. */ +(0 << 8) | /* chan 2 enable for 2:2 pull down check. */ +(0 << 9) | /* line buffer 2 enable */ +(0 << 10) | /* pre drop first. */ +(0 << 11) | /* pre repeat. */ +(0 << 12) | /* pre viu link */ +(hold_line << 16) | /* pre hold line number */ +(0 << 29) | /* pre field number. */ +(0x3 << 30) /* pre soft rst, pre frame rst. */ + ); +#ifdef SUPPORT_MPEG_TO_VDIN + if (mpeg2vdin_flag) + DI_Wr_reg_bits(DI_PRE_CTRL, 1, 13, 1); +#endif + DI_Wr(DI_MC_22LVL0, (Rd(DI_MC_22LVL0) & 0xffff0000) | 256); + DI_Wr(DI_MC_32LVL0, (Rd(DI_MC_32LVL0) & 0xffffff00) | 16); +} + +void initial_di_post_2(int hsize_post, int vsize_post, int hold_line) +{ + DI_VSYNC_WR_MPEG_REG(DI_POST_SIZE, +(hsize_post - 1) | ((vsize_post - 1) << 16)); + +#if 0 + /* di demo */ + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_X, ((hsize_post-1)>>1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_Y, (vsize_post-1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_CTRL, Rd(DI_BLEND_CTRL)| +(0x2 << 20) | /* top mode. EI only */ +25); /* KDEINT */ +#endif + /* if post size < MIN_POST_WIDTH, force old ei */ + if (hsize_post < MIN_POST_WIDTH) + DI_VSYNC_WR_MPEG_REG_BITS(DI_EI_CTRL3, 0, 31, 1); + else + DI_VSYNC_WR_MPEG_REG_BITS(DI_EI_CTRL3, 1, 31, 1); + + if (pulldown_enable) { + /* DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_Y, (vsize_post>>2)-1 ); */ + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_Y, (vsize_post-1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_Y, + ((vsize_post>>2)<<16) | (2*(vsize_post>>2)-1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_Y, + ((2*(vsize_post>>2))<<16) | (3*(vsize_post>>2)-1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_Y, + ((3*(vsize_post>>2))<<16) | (vsize_post-1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_X, (hsize_post-1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_X, (hsize_post-1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_X, (hsize_post-1)); + DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_X, (hsize_post-1)); + } + + DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, (0 << 0) | + (0 << 1) | + (0 << 2) | + (0 << 3) | + (0 << 4) | + (0 << 5) | + (0 << 6) | + (0 << 7) | + (1 << 8) | + (0 << 9) | + (0 << 10) | + (0 << 11) | + (0 << 12) | + (hold_line << 16) | + (0 << 29) | + (0x3 << 30) + ); + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { + /* enable ma,disable if0 to vpp */ + if (Rd_reg_bits(VIU_MISC_CTRL0, 16, 3) != 5) { + DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3); + if (post_wr_en) + DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, + 1, 28, 1); + } + } +} + +static unsigned int pldn_ctrl_rflsh = 1; +module_param(pldn_ctrl_rflsh, uint, 0644); +MODULE_PARM_DESC(pldn_ctrl_rflsh, "/n post blend reflesh./n"); + +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, + struct DI_SIM_MIF_s *di_mtnprd_mif, + struct DI_MC_MIF_s *di_mcvecrd_mif, + int ei_en, int blend_en, int blend_mtn_en, int blend_mode, + int di_vpp_en, int di_ddr_en, + int post_field_num, int hold_line, int urgent +) +{ + int ei_only, buf1_en; + + ei_only = ei_en && !blend_en && (di_vpp_en || di_ddr_en); + buf1_en = (!ei_only && (di_ddr_en || di_vpp_en)); + + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { + if (Rd_reg_bits(VIU_MISC_CTRL0, 16, 3) != 5) + DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3); + } + + if (ei_en || di_vpp_en || di_ddr_en) + set_di_if0_mif(di_buf0_mif, urgent, hold_line); + + if (!ei_only && (di_ddr_en || di_vpp_en)) { + DI_VSYNC_WR_MPEG_REG(DI_IF1_CANVAS0, + (di_buf1_mif->canvas0_addr2 << 16) | + (di_buf1_mif->canvas0_addr1 << 8) | + (di_buf1_mif->canvas0_addr0 << 0)); + if (is_meson_txl_cpu()) + DI_VSYNC_WR_MPEG_REG(DI_IF2_CANVAS0, + (di_buf2_mif->canvas0_addr2 << 16) | + (di_buf2_mif->canvas0_addr1 << 8) | + (di_buf2_mif->canvas0_addr0 << 0)); + #if 0 + /* post bit mode config, if0 config in video.c */ + if (is_meson_gxtvbb_cpu() || is_meson_gxl_cpu() || + is_meson_gxm_cpu()) + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG3, + di_buf1_mif->bit_mode, 8, 2); + if (is_meson_txl_cpu()) + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG3, + di_buf2_mif->bit_mode, 8, 2); + #endif + } + + /* motion for current display field. */ + if (blend_mtn_en) { + DI_VSYNC_WR_MPEG_REG(DI_MTNRD_CTRL, +(di_mtnprd_mif->canvas_num << 8) | (urgent << 16) + ); /* current field mtn canvas index. */ + + } + + if (di_ddr_en) { + DI_VSYNC_WR_MPEG_REG(DI_DIWR_CTRL, + di_diwr_mif->canvas_num | + (urgent << 16) | + (2 << 26) | + (di_ddr_en << 30)); + } + if ((pldn_ctrl_rflsh == 1) && pulldown_enable) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_en, 31, 1); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_mode, 20, 2); + if (debug_blend_mode_ctrl != 0xff) + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + debug_blend_mode_ctrl&0x3, 20, 2); + } else + DI_VSYNC_WR_MPEG_REG(DI_BLEND_CTRL, Rd(DI_BLEND_CTRL)| + (blend_en<<31) | (blend_mode<<20) | 0x1c0001f); + + if (mcpre_en) { + DI_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_CTRL, + (Rd(MCDI_MCVECRD_CTRL) & 0xffffff00) | + (1<<9) | /* canvas enable */ + di_mcvecrd_mif->canvas_num | /* canvas index. */ + (urgent << 8)); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + di_mcvecrd_mif->vecrd_offset, 12, 3); + if (di_mcvecrd_mif->blend_mode == 3) + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + mcen_mode, 0, 2); + else + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 0, 0, 2); + } + DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, + ((ei_en|blend_en) << 0) | /* line buf 0 enable */ + ((blend_mode == 1?1:0) << 1) | + (ei_en << 2) | /* ei enable */ + (blend_mtn_en << 3) | /* mtn line buffer enable */ + (blend_mtn_en << 4) |/* mtnp read mif enable */ + (blend_en << 5) | + (1 << 6) | /* di mux output enable */ + (di_ddr_en << 7) |/* di write to SDRAM enable.*/ + (di_vpp_en << 8) |/* di to VPP enable. */ + (0 << 9) | /* mif0 to VPP enable. */ + (0 << 10) | /* post drop first. */ + (0 << 11) | + (di_vpp_en << 12) | /* post viu link */ + (hold_line << 16) | /* post hold line number */ + (post_field_num << 29) | /* post field number. */ + (0x3 << 30) /* post soft rst post frame rst. */ + ); +} + +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, + struct DI_SIM_MIF_s *di_mtnprd_mif, + int ei_en, int blend_en, int blend_mtn_en, int blend_mode, + int di_vpp_en, int di_ddr_en, int post_field_num, + int hold_line, int urgent +) +{ + int ei_only; + int buf1_en; + + ei_only = ei_en && !blend_en && (di_vpp_en || di_ddr_en); + buf1_en = (!ei_only && (di_ddr_en || di_vpp_en)); + + if (ei_en || di_vpp_en || di_ddr_en) + set_di_if0_mif(di_buf0_mif, di_vpp_en, hold_line); + + /* if (!ei_only && (di_ddr_en || di_vpp_en)) */ + set_di_if1_mif(di_buf1_mif, di_vpp_en, hold_line); + if (is_meson_txl_cpu()) + set_di_if2_mif(di_buf2_mif, di_vpp_en, hold_line); + + /* printk("%s: ei_only %d,buf1_en %d,ei_en %d,di_vpp_en %d, + * di_ddr_en %d,blend_mtn_en %d,blend_mode %d.\n", + * __func__,ei_only,buf1_en,ei_en,di_vpp_en,di_ddr_en, + * blend_mtn_en,blend_mode); + */ + /* motion for current display field. */ + DI_VSYNC_WR_MPEG_REG(DI_MTNPRD_X, +(di_mtnprd_mif->start_x << 16) | (di_mtnprd_mif->end_x)); + DI_VSYNC_WR_MPEG_REG(DI_MTNPRD_Y, +(di_mtnprd_mif->start_y << 16) | (di_mtnprd_mif->end_y)); + if (blend_mtn_en) { + DI_VSYNC_WR_MPEG_REG(DI_MTNRD_CTRL, +(di_mtnprd_mif->canvas_num << 8) | (urgent << 16) + ); /* current field mtn canvas index */ + } + + if (di_ddr_en) { + DI_VSYNC_WR_MPEG_REG(DI_DIWR_X, +(di_diwr_mif->start_x << 16) | (di_diwr_mif->end_x)); + DI_VSYNC_WR_MPEG_REG(DI_DIWR_Y, (3 << 30) | +(di_diwr_mif->start_y << 16) | (di_diwr_mif->end_y)); + DI_VSYNC_WR_MPEG_REG(DI_DIWR_CTRL, + di_diwr_mif->canvas_num| + (urgent << 16) | + (2 << 26) | + (di_ddr_en << 30)); + } + + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + blend_en&0x1, 31, 1); + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + blend_mode&0x3, 20, 2); + if (debug_blend_mode_ctrl != 0xff) + DI_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + debug_blend_mode_ctrl&0x3, 20, 2); + + DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, +((ei_en | blend_en) << 0) | /* line buffer 0 enable */ +((blend_mode == 1?1:0) << 1) | +(ei_en << 2) | /* ei enable */ +(blend_mtn_en << 3) | /* mtn line buffer enable */ +(blend_mtn_en << 4) |/* mtnp read mif enable */ +(blend_en << 5) | +(1 << 6) |/* di mux output enable */ +(di_ddr_en << 7) | /* di write to SDRAM enable. */ +(di_vpp_en << 8) | /* di to VPP enable. */ +(0 << 9) | /* mif0 to VPP enable. */ +(0 << 10) | /* post drop first. */ +(0 << 11) | +(di_vpp_en << 12) | /* post viu link */ +(hold_line << 16) | /* post hold line number */ +(post_field_num << 29) | /* post field number. */ +(0x3 << 30) +/* post soft rst post frame rst. */ + ); +} + +void disable_post_deinterlace_2(void) +{ + DI_VSYNC_WR_MPEG_REG(DI_POST_CTRL, 0x3 << 30); + DI_VSYNC_WR_MPEG_REG(DI_POST_SIZE, (32-1) | ((128-1) << 16)); + DI_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, 0x3 << 30); + if (is_meson_txl_cpu()) + DI_VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG, 0x3 << 30); + if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXBB) { + /* disable ma,enable if0 to vpp,enable afbc to vpp */ + if (Rd_reg_bits(VIU_MISC_CTRL0, 16, 4) != 0) + DI_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 0, 16, 4); + /* DI inp(current data) switch to memory */ + DI_VSYNC_WR_MPEG_REG_BITS(VIUB_MISC_CTRL0, 0, 16, 1); + } + /* DI_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, + * Rd(DI_IF1_GEN_REG) & 0xfffffffe); + */ +} + +void enable_film_mode_check(unsigned int width, unsigned int height, + enum vframe_source_type_e source_type) +{ + unsigned int win0_start_x, win0_end_x, win0_start_y, win0_end_y; + unsigned int win1_start_x, win1_end_x, win1_start_y, win1_end_y; + unsigned int win2_start_x, win2_end_x, win2_start_y, win2_end_y; + unsigned int win3_start_x, win3_end_x, win3_start_y, win3_end_y; + unsigned int win4_start_x, win4_end_x, win4_start_y, win4_end_y; + + win0_start_x = win1_start_x = win2_start_x = 0; + win3_start_x = win4_start_x = 0; + win0_end_x = win1_end_x = win2_end_x = width-1; + win3_end_x = win4_end_x = width-1; + win0_start_y = 0; + win1_start_y = (height>>3); /* 1/8 */ + win0_end_y = win1_start_y - 1; + win2_start_y = win1_start_y + (height>>2); /* 1/4 */ + win1_end_y = win2_start_y - 1; + win3_start_y = win2_start_y + (height>>2); /* 1/4 */ + win2_end_y = win3_start_y - 1; + win4_start_y = win3_start_y + (height>>2); /* 1/4 */ + win3_end_y = win4_start_y - 1; + win4_end_y = win4_start_y + (height>>3) - 1; /* 1/8 */ + + pd_win_prop[0].pixels_num = +(win0_end_x-win0_start_x)*(win0_end_y-win0_start_y); + pd_win_prop[1].pixels_num = +(win1_end_x-win1_start_x)*(win1_end_y-win1_start_y); + pd_win_prop[2].pixels_num = +(win2_end_x-win2_start_x)*(win2_end_y-win2_start_y); + pd_win_prop[3].pixels_num = +(win3_end_x-win3_start_x)*(win3_end_y-win3_start_y); + pd_win_prop[4].pixels_num = +(win4_end_x-win4_start_x)*(win4_end_y-win4_start_y); + + RDMA_WR(DI_MC_REG0_X, (win0_start_x << 16) | win0_end_x); + RDMA_WR(DI_MC_REG0_Y, (win0_start_y << 16) | win0_end_y); + RDMA_WR(DI_MC_REG1_X, (win1_start_x << 16) | win1_end_x); + RDMA_WR(DI_MC_REG1_Y, (win1_start_y << 16) | win1_end_y); + RDMA_WR(DI_MC_REG2_X, (win2_start_x << 16) | win2_end_x); + RDMA_WR(DI_MC_REG2_Y, (win2_start_y << 16) | win2_end_y); + RDMA_WR(DI_MC_REG3_X, (win3_start_x << 16) | win3_end_x); + RDMA_WR(DI_MC_REG3_Y, (win3_start_y << 16) | win3_end_y); + RDMA_WR(DI_MC_REG4_X, (win4_start_x << 16) | win4_end_x); + RDMA_WR(DI_MC_REG4_Y, (win4_start_y << 16) | win4_end_y); + +} + +static int fdn[5] = {0}; +bool read_pulldown_info(pulldown_detect_info_t *field_pd_info, + pulldown_detect_info_t *win_pd_info) +{ + int i; + unsigned long pd_info[6]; + unsigned long tmp; + + DI_Wr(DI_INFO_ADDR, 0); + for (i = 0; i < 6; i++) + pd_info[i] = Rd(DI_INFO_DATA); + + memset(field_pd_info, 0, sizeof(pulldown_detect_info_t)); + field_pd_info->field_diff = pd_info[2]; + field_pd_info->field_diff_num = pd_info[4]&0xffffff; + field_pd_info->frame_diff = pd_info[0]; + field_pd_info->frame_diff_num = pd_info[1]&0xffffff; + + fdn[0] = fdn[1]; + fdn[1] = fdn[2]; + fdn[2] = fdn[3]; + fdn[3] = fdn[4]; + fdn[4] = field_pd_info->frame_diff_num; + /* if (fdn[0] || fdn[1] || fdn[2] || fdn[3] || fdn[4]) */ + if (frame_dynamic_dbg) + pr_dbg("\n fdn[4]= %x", fdn[4]); + if (frame_dynamic_level == 0) + fdn[4] = fdn[4]&0xffff00; + else if (frame_dynamic_level == 1) + fdn[4] = fdn[4]&0xfffe00; + else if (frame_dynamic_level == 2) + fdn[4] = fdn[4]&0xfffc00; + else if (frame_dynamic_level == 3) + fdn[4] = fdn[4]&0xfff800; + else if (frame_dynamic_level == 4) + fdn[4] = fdn[4]&0xfff000; + else + fdn[4] = fdn[4]&0xffff00; + if ((fdn[0]&0xffff00) || fdn[1] || fdn[2] || fdn[3] || fdn[4]) + frame_dynamic = true; + else + frame_dynamic = false; + + for (i = 0; i < MAX_WIN_NUM; i++) + memset(&(win_pd_info[i]), 0, sizeof(pulldown_detect_info_t)); + + for (i = 0; i < MAX_WIN_NUM; i++) + win_pd_info[i].frame_diff = Rd(DI_INFO_DATA); + + for (i = 0; i < MAX_WIN_NUM; i++) + win_pd_info[i].field_diff = Rd(DI_INFO_DATA); + + for (i = 0; i < MAX_WIN_NUM; i++) + tmp = Rd(DI_INFO_DATA); /* luma */ + + for (i = 0; i < MAX_WIN_NUM; i++) + win_pd_info[i].frame_diff_num = Rd(DI_INFO_DATA)&0xffffff; + + for (i = 0; i < MAX_WIN_NUM; i++) + win_pd_info[i].field_diff_num = +(Rd(DI_INFO_DATA)&0xfffff)<<4; + + return frame_dynamic; +} + +void read_new_pulldown_info(struct FlmModReg_t *pFMReg) +{ + int i = 0; + + for (i = 0; i < 6; i++) { + pFMReg->rROFrmDif02[i] = Rd(DIPD_RO_COMB_0+i); + pFMReg->rROFldDif01[i] = Rd(DIPD_RO_COMB_6+i); + } + + /* pFMReg->rROFrmDif02[0] = Rd(DIPD_RO_COMB_0); */ + /* pFMReg->rROFldDif01[0] = Rd(DIPD_RO_COMB_6); */ + + for (i = 0; i < 9; i++) + pFMReg->rROCmbInf[i] = Rd(DIPD_RO_COMB_12+i); +} + +void di_post_read_reverse(bool reverse) +{ +#ifdef NEW_DI_TV + if (reverse) { + DI_Wr_reg_bits(DI_IF1_GEN_REG2, 3, 2, 2); + DI_Wr_reg_bits(VD1_IF0_GEN_REG2, 0xf, 2, 4); + DI_Wr_reg_bits(VD2_IF0_GEN_REG2, 0xf, 2, 4); + if (mcpre_en) { + /* motion vector read reverse*/ + DI_Wr_reg_bits(MCDI_MCVECRD_X, 1, 30, 1); + DI_Wr_reg_bits(MCDI_MCVECRD_Y, 1, 30, 1); + DI_Wr_reg_bits(MCDI_MC_CRTL, 0, 8, 1); + } + } else { + DI_Wr_reg_bits(DI_IF1_GEN_REG2, 0, 2, 2); + DI_Wr_reg_bits(VD1_IF0_GEN_REG2, 0, 2, 4); + DI_Wr_reg_bits(VD2_IF0_GEN_REG2, 0, 2, 4); + if (mcpre_en) { + DI_Wr_reg_bits(MCDI_MCVECRD_X, 0, 30, 1); + DI_Wr_reg_bits(MCDI_MCVECRD_Y, 0, 30, 1); + DI_Wr_reg_bits(MCDI_MC_CRTL, 1, 8, 1); + } + } +#endif +} +void di_post_read_reverse_irq(bool reverse) +{ + if (reverse) { + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG2, 3, 2, 2); + DI_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0xf, 2, 4); + DI_VSYNC_WR_MPEG_REG_BITS(VD2_IF0_GEN_REG2, 0xf, 2, 4); + DI_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0xf, 17, 4); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG2, 3, 2, 2); + if (mcpre_en) { + /* motion vector read reverse*/ + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_X, 1, 30, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_Y, 1, 30, 1); + if (is_meson_txl_cpu()) + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + mc_pre_flag, 8, 2); + else + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 0, 8, 1); + } + } else { + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG2, 0, 2, 2); + DI_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0, 2, 4); + DI_VSYNC_WR_MPEG_REG_BITS(VD2_IF0_GEN_REG2, 0, 2, 4); + DI_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0, 17, 4); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + DI_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG2, 0, 2, 2); + if (mcpre_en) { + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_X, 0, 30, 1); + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_Y, 0, 30, 1); + if (is_meson_txl_cpu()) + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + mc_pre_flag, 8, 2); + else + DI_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 1, 8, 1); + } + } +} + +void diwr_set_power_control(unsigned char enable) +{ + switch_vpu_mem_pd_vmod(VPU_VIU_VD1, + enable?VPU_MEM_POWER_ON:VPU_MEM_POWER_DOWN); + switch_vpu_mem_pd_vmod(VPU_DI_POST, + enable?VPU_MEM_POWER_ON:VPU_MEM_POWER_DOWN); +} + + +static unsigned char pre_power_on; +static unsigned char post_power_on; +void di_set_power_control(unsigned char type, unsigned char enable) +{ + if (di_debug_flag&0x20) + return; + if (type == 0) { + /* WRITE_MPEG_REG_BITS(HHI_VPU_MEM_PD_REG0, + * enable?0:3, 26, 2); //di pre + */ + switch_vpu_mem_pd_vmod(VPU_DI_PRE, +enable?VPU_MEM_POWER_ON:VPU_MEM_POWER_DOWN); + pre_power_on = enable; + } + if (type == 1) + post_power_on = enable; +} + +unsigned char di_get_power_control(unsigned char type) +{ + if (type == 0) + return pre_power_on; + +#if 0 +/* let video.c handle it */ + return 1; +#else + return post_power_on; +#endif + + +} + +void enable_di_pre_mif(int en) +{ + if (en) { + /* enable input mif*/ + DI_Wr(DI_CHAN2_GEN_REG, Rd(DI_CHAN2_GEN_REG) | 0x1); + DI_Wr(DI_MEM_GEN_REG, Rd(DI_MEM_GEN_REG) | 0x1); + DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) | 0x1); + /* nrwr no clk gate en=0 */ + RDMA_WR_BITS(DI_NRWR_CTRL, 0, 24, 1); + if (mcpre_en) { + /* gate clk */ + RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 9, 1); + /* gate clk */ + RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 9, 1); + } + /* enable di nr/mtn/mv mif */ + RDMA_WR(VPU_WRARB_REQEN_SLV_L1C1, 0x3f); + } else { + /* nrwr no clk gate en=1 */ + RDMA_WR_BITS(DI_NRWR_CTRL, 1, 24, 1); + /* nr wr req en =0 */ + RDMA_WR_BITS(DI_PRE_CTRL, 0, 0, 1); + /* mtn wr req en =0 */ + RDMA_WR_BITS(DI_PRE_CTRL, 0, 1, 1); + /* cont wr req en =0 */ + RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 31, 1); + if (mcpre_en) { + /* no gate clk */ + RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 9, 1); + /* no gate clk */ + RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 9, 1); + /* mcvec wr req en =0 */ + RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 12, 1); + /* mcinfo wr req en =0 */ + RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 12, 1); + /* mcinfo rd req en = 0 */ + RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 0, 9, 1); + } + /* disable nr cont mtn mv minfo mif */ + RDMA_WR(VPU_WRARB_REQEN_SLV_L1C1, 0x2b); + /* disable cont rd */ + DI_Wr(DI_PRE_CTRL, Rd(DI_PRE_CTRL) & ~(1 << 25)); + /* disable input mif*/ + DI_Wr(DI_CHAN2_GEN_REG, Rd(DI_CHAN2_GEN_REG) & ~0x1); + DI_Wr(DI_MEM_GEN_REG, Rd(DI_MEM_GEN_REG) & ~0x1); + DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) & ~0x1); + } +} + +void combing_pd22_window_config(unsigned int width, unsigned int height) +{ + unsigned short y1 = 39, y2 = height - 41; + + if (width == 1080) { + y1 = 79; + y2 = height - 81; + } + + DI_Wr_reg_bits(DECOMB_WIND00, 0, 16, 13);/* dcomb x0 */ + DI_Wr_reg_bits(DECOMB_WIND00, (width-1), 0, 13);/* dcomb x1 */ + DI_Wr_reg_bits(DECOMB_WIND01, 0, 16, 13);/* dcomb y0 */ + DI_Wr_reg_bits(DECOMB_WIND01, y1, 0, 13);/* dcomb y1 */ + DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_X, 0, 0, 13);/* pd22 x0 */ + DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_X, (width-1), 16, 13);/* pd22 x1 */ + DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_Y, 0, 0, 13);/* pd22 y0 */ + DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_Y, y1, 16, 13);/* pd y1 */ + + DI_Wr_reg_bits(DECOMB_WIND10, 0, 16, 13);/* dcomb x0 */ + DI_Wr_reg_bits(DECOMB_WIND10, (width-1), 0, 13);/* dcomb x1 */ + DI_Wr_reg_bits(DECOMB_WIND11, (y1+1), 16, 13);/* dcomb y0 */ + DI_Wr_reg_bits(DECOMB_WIND11, y2, 0, 13);/* dcomb y1 */ + DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_X, 0, 0, 13);/* pd x0 */ + DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_X, (width-1), 16, 13);/* pd x1 */ + DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_Y, (y1+1), 0, 13);/* pd y0 */ + DI_Wr_reg_bits(DECOMB_WIND11, y2, 16, 13);/* pd y1 */ + +} diff --git a/drivers/amlogic/media/deinterlace/deinterlace_mtn.c b/drivers/amlogic/media/deinterlace/deinterlace_mtn.c new file mode 100644 index 000000000000..3559cc9c047d --- /dev/null +++ b/drivers/amlogic/media/deinterlace/deinterlace_mtn.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; + } +} diff --git a/drivers/amlogic/media/deinterlace/deinterlace_mtn.h b/drivers/amlogic/media/deinterlace/deinterlace_mtn.h new file mode 100644 index 000000000000..49d7b1d9d53a --- /dev/null +++ b/drivers/amlogic/media/deinterlace/deinterlace_mtn.h @@ -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); + diff --git a/drivers/amlogic/media/deinterlace/detect3d.c b/drivers/amlogic/media/deinterlace/detect3d.c new file mode 100644 index 000000000000..958634efdd52 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/detect3d.c @@ -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 +#include +/* Amlogic Headers */ + +#include +#include +#include + +#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"); + diff --git a/drivers/amlogic/media/deinterlace/detect3d.h b/drivers/amlogic/media/deinterlace/detect3d.h new file mode 100644 index 000000000000..efead1b27cec --- /dev/null +++ b/drivers/amlogic/media/deinterlace/detect3d.h @@ -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 */ diff --git a/drivers/amlogic/media/deinterlace/film_fw1.c b/drivers/amlogic/media/deinterlace/film_fw1.c new file mode 100644 index 000000000000..a52d80d7866b --- /dev/null +++ b/drivers/amlogic/media/deinterlace/film_fw1.c @@ -0,0 +1,1456 @@ +/* + * drivers/amlogic/media/deinterlace/film_fw1.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include "film_vof_soft.h" + +/* Software parameters (registers) */ +UINT8 FlmVOFSftInt(struct sFlmSftPar *pPar) +{ + pPar->sFrmDifAvgRat = 16; /* 0~32 */ + /* The Large Decision should be: (large>average+LgDifThrd) */ + pPar->sFrmDifLgTDif = 4096; + pPar->sF32StpWgt01 = 15; + pPar->sF32StpWgt02 = 15; + /* Dif>Rat*Min --> Larger */ + pPar->sF32DifLgRat = 16; + + pPar->sFlm2MinAlpha = 32; /* [0~63] */ + pPar->sFlm2MinBelta = 32; /* [0~63] */ + pPar->sFlm20ftAlpha = 16; /* [0~63] */ + pPar->sFlm2LgDifThd = 4096; /* [0~63] %LgDifThrd */ + pPar->sFlm2LgFlgThd = 8; + + pPar->sF32Dif01A1 = 65; + pPar->sF32Dif01T1 = 128; + pPar->sF32Dif01A2 = 65; + pPar->sF32Dif01T2 = 128; + + pPar->rCmbRwMinCt0 = 8; /* for film 3-2 */ + pPar->rCmbRwMinCt1 = 7; /* for film 2-2 */ + + pPar->sFlm32NCmb = 8; /* absolute no combing for film 32 */ + /* pre-processing (t-0), post-processing f(t-mPstDlyPre); No RTL */ + pPar->mPstDlyPre = 1; + /* pre-processing (t-0), pre-processing f(t+mNxtDlySft); + * No RTL,default=1 + */ + pPar->mNxtDlySft = 1; + + pPar->sF32Dif02M0 = 4096; /* mpeg-4096, cvbs-8192 */ + pPar->sF32Dif02M1 = 4096; + + field_count = 0; + + return 0; +} + +/* Outputs: + * rCmb32Spcl: 1-bit, 0/1 + * rPstCYWnd0~4[0]: bgn, + * rPstCYWnd0~4[1]: end, + * rPstCYWnd0~4[2]: 0-mtn,1-with-buffer,2-ei,3-di, + * rFlmPstGCm: 1-bit, global combing (maybe unused) + * rFlmSltPre: 1-bit, 0-next field, 1-previous field + * rFlmPstMod: 2-bit, 00-no, 01-22, 10-23, 11-other + * Inputs: + * rROFldDif01: difference f(t) and f(t-1), U32 + * rROFldDif02: difference f(t) and f(t-2), U32 + * rROCmbInf[9]: U32 x 9 + * nROW: (240 for 480i) + */ + +unsigned int pr_pd; +module_param(pr_pd, uint, 0644); +MODULE_PARM_DESC(pr_pd, "/n printk /n"); + +bool prt_flg; +module_param(prt_flg, bool, 0644); +MODULE_PARM_DESC(prt_flg, "/n prt_flg /n"); + +char debug_str[512]; + +/* if flmxx level > flmxx_first_num */ +/* flmxx first: even when 2-2 3-2 detected */ +/* unsigned int flmxx_first_num = 50; */ +/* module_param(flmxx_first_num, uint, 0644); */ +/* MODULE_PARM_DESC(flmxx_first_num, */ +/* "/n flmxx first: even when 2-2 3-2 detected /n"); */ + +/* if flmxx level > flmxx_maybe_num */ +/* mabye flmxx: when 2-2 3-2 not detected */ +unsigned int flmxx_maybe_num = 15; +module_param(flmxx_maybe_num, uint, 0644); +MODULE_PARM_DESC(flmxx_maybe_num, +"/n mabye flmxx: when 2-2 3-2 not detected /n"); + +int flm32_mim_frms = 6; +module_param(flm32_mim_frms, int, 0644); +MODULE_PARM_DESC(flm32_mim_frms, "flm32_mim_frms"); + +int flm22_mim_frms = 60; +module_param(flm22_mim_frms, int, 0644); +MODULE_PARM_DESC(flm22_mim_frms, "flm22_mim_frms"); + +int flm22_mim_smfrms = 40; +module_param(flm22_mim_smfrms, int, 0644); +MODULE_PARM_DESC(flm22_mim_smfrms, "flm22_mim_smfrms"); + +int flm32_f2fdif_min0 = 11; +module_param(flm32_f2fdif_min0, int, 0644); +MODULE_PARM_DESC(flm32_f2fdif_min0, "flm32_f2fdif_min0"); + +int flm32_f2fdif_min1 = 11; +module_param(flm32_f2fdif_min1, int, 0644); +MODULE_PARM_DESC(flm32_f2fdif_min1, "flm32_f2fdif_min1"); + +int flm32_chk1_rtn = 25; +module_param(flm32_chk1_rtn, int, 0644); +MODULE_PARM_DESC(flm32_chk1_rtn, "flm32_chk1_rtn"); + +int flm32_ck13_rtn = 8; +module_param(flm32_ck13_rtn, int, 0644); +MODULE_PARM_DESC(flm32_ck13_rtn, "flm32_ck13_rtn"); + +int flm32_chk2_rtn = 16; +module_param(flm32_chk2_rtn, int, 0644); +MODULE_PARM_DESC(flm32_chk2_rtn, "flm32_chk2_rtn"); + +int flm32_chk3_rtn = 16; +module_param(flm32_chk3_rtn, int, 0644); +MODULE_PARM_DESC(flm32_chk3_rtn, "flm32_chk3_rtn"); + +int flm22_chk20_sml = 6; +module_param(flm22_chk20_sml, int, 0644); +MODULE_PARM_DESC(flm22_chk20_sml, "flm22_chk20_sml"); + +int flm22_chk21_sml = 6; +module_param(flm22_chk21_sml, int, 0644); +MODULE_PARM_DESC(flm22_chk21_sml, "flm22_chk21_sml"); + +int flm22_chk21_sm2 = 10; +module_param(flm22_chk21_sm2, int, 0644); +MODULE_PARM_DESC(flm22_chk21_sm2, "flm22_chk21_sm2"); + +int flm22_lavg_sft = 4; +module_param(flm22_lavg_sft, int, 0644); +MODULE_PARM_DESC(flm22_lavg_sft, "flm22_lavg_sft"); + +int flm22_lavg_lg = 24; +module_param(flm22_lavg_lg, int, 0644); +MODULE_PARM_DESC(flm22_lavg_lg, "flm22_lavg_lg"); + +/* dif02 < (size >> sft) => static */ +int flm22_stl_sft = 7; /*10*/ +module_param(flm22_stl_sft, int, 0644); +MODULE_PARM_DESC(flm22_stl_sft, "flm22_stl_sft"); + +int flm22_chk5_avg = 50; +module_param(flm22_chk5_avg, int, 0644); +MODULE_PARM_DESC(flm22_chk5_avg, "flm22_chk5_avg"); + +int flm22_chk6_max = 20; +module_param(flm22_chk6_max, int, 0644); +MODULE_PARM_DESC(flm22_chk6_max, "flm22_chk6_max"); + +int flm22_anti_chk1 = 61; +module_param(flm22_anti_chk1, int, 0644); +MODULE_PARM_DESC(flm22_anti_chk1, "flm22_anti_chk1"); + +int flm22_anti_chk3 = 140; +module_param(flm22_anti_chk3, int, 0644); +MODULE_PARM_DESC(flm22_anti_chk3, "flm22_anti_chk3"); + +int flm22_anti_chk4 = 128; +module_param(flm22_anti_chk4, int, 0644); +MODULE_PARM_DESC(flm22_anti_chk4, "flm22_anti_chk4"); + +int flm22_anti_ck140 = 32; +module_param(flm22_anti_ck140, int, 0644); +MODULE_PARM_DESC(flm22_anti_ck140, "flm22_anti_ck140"); + +int flm22_anti_ck141 = 80; +module_param(flm22_anti_ck141, int, 0644); +MODULE_PARM_DESC(flm22_anti_ck141, "flm22_anti_ck141"); + +int flm22_frmdif_max = 50; +module_param(flm22_frmdif_max, int, 0644); +MODULE_PARM_DESC(flm22_frmdif_max, "flm22_frmdif_max"); + +int flm22_flddif_max = 100; +module_param(flm22_flddif_max, int, 0644); +MODULE_PARM_DESC(flm22_flddif_max, "flm22_flddif_max"); + +int flm22_minus_cntmax = 2; +module_param(flm22_minus_cntmax, int, 0644); +MODULE_PARM_DESC(flm22_minus_cntmax, "flm22_minus_cntmax"); + + +int FlmVOFSftTop(UINT8 *rCmb32Spcl, unsigned short *rPstCYWnd0, + unsigned short *rPstCYWnd1, unsigned short *rPstCYWnd2, + unsigned short *rPstCYWnd3, unsigned short *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) +{ + static UINT32 DIF01[HISDIFNUM]; /* Last one is global */ + static UINT32 DIF02[HISDIFNUM]; /* Last one is global */ + /* Dif01 of 5th windows used for 2-2 */ + static UINT32 DifW5[HISDIFNUM]; + + static struct sFlmDatSt pRDat; + static int pre22lvl; + static UINT32 pre_fld_motnum; + + int nDIF01[HISDIFNUM]; + int nDIF02[HISDIFNUM]; + /* UINT32 nCb32=0; */ + unsigned int ntmp = 0; + unsigned int flm22_mim_numb = 0; + + /* int nRCMB[ROWCMBNUM]; */ + int mDly = pPar->mPstDlyPre; + int mNDly = pPar->mNxtDlySft; + + int nT0 = 0; + int nT1 = 0; + int nS0 = 0; + int nS1 = 0; + int nMod = 0; + + /* difference */ + pRDat.rROFrmDif02 = rROFrmDif02; + /* size of the image */ + pRDat.iHeight = nROW; /* field height */ + pRDat.iWidth = nCOL; + + prt_flg = 0; + debug_str[0] = '\0'; + + /* Initialization */ + if (field_count < 3) { + for (nT1 = 0; nT1 < HISDIFNUM; nT1++) { + DIF01[nT1] = 0xffffffff; + DIF02[nT1] = 0xffffffff; + DifW5[nT1] = 0xffffffff; + } + + for (nT1 = 0; nT1 < HISDETNUM; nT1++) { + pRDat.pFlg32[nT1] = 0; + pRDat.pMod32[nT1] = 0; + pRDat.mNum32[nT1] = 0; + + pRDat.pFld32[nT1] = 0; + pRDat.pFrm32[nT1] = 0; + pRDat.pFrm32t[nT1] = 0; + + pRDat.pFlg22[nT1] = 0; + pRDat.pMod22[nT1] = 0; + pRDat.mNum22[nT1] = 0; + + pRDat.pStp22[nT1] = 0; + pRDat.pSmp22[nT1] = 0; + + /* HISDETNUM hist */ + pRDat.pModXx[nT1] = 0; + pRDat.pFlgXx[nT1] = 0; /* pre-1, nxt-0 */ + pRDat.pLvlXx[nT1] = 0; /* mode level */ + } + } else { + for (nT1 = 1; nT1 < HISDETNUM; nT1++) { + pRDat.mNum32[nT1 - 1] = pRDat.mNum32[nT1]; + pRDat.mNum22[nT1 - 1] = pRDat.mNum22[nT1]; + } + } + + /* -------------------------------------------------------------- */ + nS0 = 0; + nS1 = 0; + /* int rROFrmDif02[6]; // Read only */ + /* int rROFldDif01[6]; // Read only */ + for (nT1 = 1; nT1 < HISDIFNUM; nT1++) { + DIF01[nT1 - 1] = DIF01[nT1]; + DIF02[nT1 - 1] = DIF02[nT1]; + DifW5[nT1-1] = DifW5[nT1]; + } + + DIF01[HISDIFNUM - 1] = rROFldDif01[0]; /* 5windows+global */ + DIF02[HISDIFNUM - 1] = rROFrmDif02[0]; /* 5windows+global */ + + if (pr_pd) { + sprintf(debug_str, "\nField#%5d: [%4dx%4d]\n", + field_count, nROW, nCOL); + sprintf(debug_str + strlen(debug_str), + "diff counter: %4d %4d\n", + glb_field_mot_num, glb_frame_mot_num); + } + + prt_flg = (pr_pd & 0x1); + if (prt_flg) { + sprintf(debug_str + strlen(debug_str), "Dif012=[%u,%u]\n", + DIF01[HISDIFNUM - 1], DIF02[HISDIFNUM - 1]); + + for (nT1 = 1; nT1 < 6; nT1++) + sprintf(debug_str + strlen(debug_str), + "WDif12[%d]=[%u,%u]\n", nT1, + rROFldDif01[nT1], rROFrmDif02[nT1]); + + for (nT1 = 0; nT1 < ROWCMBLEN; nT1++) + sprintf(debug_str + strlen(debug_str), + "rROCmbInf[%d]=%08x\n", nT1, + rROCmbInf[nT1]); + } + if (pr_pd) + pr_info("%s", debug_str); + + /* --------------------------------------------------------------- */ + /* int nDIF01[HISDIFNUM]; */ + /* int nDIF02[HISDIFNUM]; */ + for (nT1 = 0; nT1 < HISDIFNUM; nT1++) { + nDIF01[nT1] = DIF01[nT1]; + nDIF02[nT1] = DIF02[nT1]; + } + /* --------------------------------------------------------- */ + /* Film-Detection */ + nS1 = FlmDetSft(&pRDat, nDIF01, nDIF02, nT0, pPar); + + nS0 = FlmModsDet(&pRDat, rROFldDif01[0], rROFrmDif02[0]); + /* --------------------------------------------------------- */ + + /* for panda 2-2 : flag 1, 3 */ + if (pRDat.pFlg22[HISDETNUM-1] & 0x1) { + /* diff01 of the 5th window */ + /* for panda 2-2: VOF */ + DifW5[HISDIFNUM-1] = + (16 * rROFldDif01[5]) / (rROFldDif01[0] + 16); + nT1 = (DifW5[HISDIFNUM-1] << 2); + if (nS1 > nT1) + nS1 -= nT1; /* reset the 5th window */ + + pre22lvl = nS1; + } else if (pRDat.pFlg22[HISDETNUM-1]) + nS1 = pre22lvl; + else + pre22lvl = 0; + + /* Current f(t-0) with previous */ + /* pFMReg->rCmb32Spcl =0; */ + *rCmb32Spcl = 0; + if (pRDat.pMod32[HISDETNUM - 1] == 3) { + nMod = pRDat.pMod32[HISDETNUM - 1]; + /* nT0 = pRDat.pFlg32[HISDETNUM - 1] % 2; */ + + if (pRDat.mNum32[HISDETNUM - 1] < 255) /* maximum */ + pRDat.mNum32[HISDETNUM - 1] += 1; + + /* 3-2 film combing special precessing (A-A-A) */ + if (pRDat.pFlg32[HISDETNUM - 1] == (mNDly % 5)) + *rCmb32Spcl = 1; + } else if (pRDat.pMod22[HISDETNUM - 1] == 2) { + nMod = pRDat.pMod22[HISDETNUM - 1]; + /* nT0 = pRDat.pFlg22[HISDETNUM - 1] % 2; */ + + if (pRDat.mNum22[HISDETNUM - 1] < 255) /* maximum */ + pRDat.mNum22[HISDETNUM - 1] += 1; + } else { + nMod = 0; + + pRDat.mNum32[HISDETNUM - 1] = 0; + pRDat.mNum22[HISDETNUM - 1] = 0; + } + + /* Only frame (t-1) */ + /* pFMReg->rFlmPstGCm = 0; */ + *rFlmPstGCm = 0; + *frame_diff_avg = DIF02[HISDIFNUM-1] / (glb_frame_mot_num + 1); + /* rFlmPstGCm = 1; */ + if (pRDat.pMod32[HISDETNUM - 1 - mDly] == 3) { + nT0 = pRDat.pFlg32[HISDETNUM - 1 - mDly] % 2; + *rFlmSltPre = nT0; + /* Post-processing: film mode,00: global combing, + * 01: 2-2 film, 10: 2-3 film, 11:-others + */ + *rFlmPstMod = 2; + /* param: at least 5 field+5 */ + if (pRDat.mNum32[HISDETNUM - 1] < flm32_mim_frms) { + *rFlmSltPre = 0; + *rFlmPstMod = 0; + } + nS1 = 0; + } else if (pRDat.pMod22[HISDETNUM - 1 - mDly] == 2) { + nT0 = pRDat.pFlg22[HISDETNUM - 1 - mDly] % 2; + *rFlmSltPre = nT0; + /* Post-processing: film mode, + * 00: global combing, 01: 2-2 film, 10: 2-3 film, 11:-others + */ + *rFlmPstMod = 1; + + ntmp = (glb_frame_mot_num + glb_field_mot_num) / + (nCOL + 1); + if (flm22_mim_frms > ntmp + flm22_mim_smfrms) + flm22_mim_numb = flm22_mim_frms - ntmp; + else + flm22_mim_numb = flm22_mim_smfrms; + + if (pr_pd) + pr_info("diff02-avg=%4d\n", *frame_diff_avg); + if (*frame_diff_avg > flm22_frmdif_max) { + ntmp = *frame_diff_avg - flm22_frmdif_max; + if (ntmp > flm22_minus_cntmax) + ntmp = flm22_minus_cntmax; + if (pRDat.mNum22[HISDETNUM - 1] > ntmp) + pRDat.mNum22[HISDETNUM - 1] = + pRDat.mNum22[HISDETNUM - 1] - ntmp; + else + pRDat.mNum22[HISDETNUM - 1] = 0; + } + + if (DIF01[HISDIFNUM-1] < DIF01[HISDIFNUM-2]) { + /*ntmp = DIF01[HISDIFNUM-1] / (glb_field_mot_num + 1);*/ + /* min / max */ + ntmp = DIF01[HISDIFNUM-1] / (pre_fld_motnum + 1); + + if (pr_pd) + pr_info("diff01-avg=%4d\n", ntmp); + if (ntmp > flm22_flddif_max) { + ntmp = ntmp - flm22_flddif_max; + + if (ntmp > flm22_minus_cntmax) + ntmp = flm22_minus_cntmax; + + if (pRDat.mNum22[HISDETNUM - 1] > ntmp) + pRDat.mNum22[HISDETNUM - 1] = + pRDat.mNum22[HISDETNUM - 1] - ntmp; + else + pRDat.mNum22[HISDETNUM - 1] = 0; + } + } + + /* param: at least 60 field+4 */ + if (pRDat.mNum22[HISDETNUM - 1] < flm22_mim_numb) { + *rFlmSltPre = 0; + *rFlmPstMod = 0; + if (pr_pd) + pr_info("mNum22(%3d) < %03d => set to mod=0\n", + pRDat.mNum22[HISDETNUM - 1], flm22_mim_frms); + } + } else { + *rFlmSltPre = 0; + /* Post-processing: film mode,00: global combing, + * 01: 2-2 film, 10: 2-3 film, 11:-others + */ + *rFlmPstMod = 0; + nS1 = 0; + } + pre_fld_motnum = glb_field_mot_num; + + VOFSftTop(rFlmPstGCm, rFlmSltPre, rFlmPstMod, + rPstCYWnd0, rPstCYWnd1, rPstCYWnd2, rPstCYWnd3, + nMod, rROCmbInf, &pRDat, pPar, nROW, nCOL); + + nT1 = pRDat.pLvlXx[HISDETNUM - 1 - mDly]; + if ((*rFlmPstMod == 0) && (nT1 > flmxx_maybe_num) + && (nS0 != 6) && (pRDat.pMod22[HISDETNUM - 1 - mDly] != 2)) { + *rFlmSltPre = pRDat.pFlgXx[HISDETNUM - 1 - mDly]; + *rFlmPstMod = 4 + pRDat.pModXx[HISDETNUM - 1 - mDly]; + nS1 = pRDat.pLvlXx[HISDETNUM - 1 - mDly]; + } + + *tTCNm = pRDat.TCNm[HISCMBNUM - 1]; + return nS1; +} + +/* Film Detection Software implementation */ +/* nDif01: Field Difference */ +/* nDif02: Frame Difference */ +/* WND: The index of Window */ +int FlmDetSft(struct sFlmDatSt *pRDat, int *nDif01, int *nDif02, + int WND, struct sFlmSftPar *pPar) +{ + int nT0 = 0; + + /* 3-2 */ + Flm32DetSft(pRDat, nDif02, nDif01, pPar); + + /* Film2-2 Detection */ + /* debug0304 */ + nT0 = Flm22DetSft(pRDat, nDif02, nDif01, pPar); + /* ---------------------------------------- */ + prt_flg = 0; + return nT0; +} + +/* pFlm02[0:nLEN-1] : recursive, 0-2 dif */ +/* pFlm01[0:nLEN-1] : recursive, 0-1 dif */ +int Flm32DetSft(struct sFlmDatSt *pRDat, int *nDif02, + int *nDif01, struct sFlmSftPar *pPar) +{ + int sFrmDifAvgRat = pPar->sFrmDifAvgRat; /* 16; //0~32 */ + /* The Large Decision should be: (large>average+LgDifThrd) */ + int sFrmDifLgTDif = pPar->sFrmDifLgTDif; /* 4096 */ + int sF32StpWgt01 = pPar->sF32StpWgt01; /* 15; */ + int sF32StpWgt02 = pPar->sF32StpWgt02; /* 15; */ + int sF32DifLgRat = pPar->sF32DifLgRat; /* 16; Dif>Rat*Min-->Larger */ + + /* int sF32DifSmRat = 16; //Dif*Rat Smaller */ + + UINT8 *pFlm02 = pRDat->pFrm32; + UINT8 *pFlm02t = pRDat->pFrm32t; + UINT8 *pFlm01 = pRDat->pFld32; + UINT8 *pFlg32 = pRDat->pFlg32; + + static UINT8 sFld32[6] = { 0, 0, 0, 0, 0, 0 }; + + UINT8 FIX02[2][5] = { {2, 3, 4, 5, 1}, {4, 5, 1, 2, 3} }; + + int nT0 = 0; + int nT1 = 0; + int nT2 = 0; + + int nMn = nDif02[HISDIFNUM - 1]; + int nMx = nDif02[HISDIFNUM - 1]; + int nSM = nDif02[HISDIFNUM - 1]; + UINT8 nFlg01[6] = { 0, 0, 0, 0, 0, 0 }; + UINT8 nFlg02[6] = { 0, 0, 0, 0, 0, 0 }; + UINT8 nFlg12[6] = { 0, 0, 0, 0, 0, 0 }; + + int nAV10 = 0; + int nAV11 = 0; + int nAV12 = 0; + int nAV1 = 0; + int nSTP = 0; + UINT8 nMIX = 0; + + int nFlgChk1 = 0; + int nFlgChk2 = 0; + int nFlgChk3 = 0; /* for Mit32VHLine */ + + prt_flg = ((pr_pd >> 2) & 0x1); + if (prt_flg) + sprintf(debug_str, "#Dbg32:\n"); + + /* ---------------------------------- */ + /* Get min/max from the last fives */ + for (nT0 = 2; nT0 <= 5; nT0++) { + nT1 = nDif02[HISDIFNUM - nT0]; + nSM += nT1; + + if (nT1 < nMn) + nMn = nT1; + + if (nT1 > nMx) + nMx = nT1; + } + nAV10 = ((nSM - nMx + 2) >> 2); + nAV12 = ((nSM + 3 * nMn + 4) >> 3); + + nSM = 0; + nT2 = 0; + for (nT0 = 1; nT0 <= 5; nT0++) { + nT1 = nDif02[HISDIFNUM - nT0]; + if (nT1 >= nAV10) { + nT2 += 1; + nSM += nT1; + } + } + nAV11 = (nSM - nMx + nT2 / 2) / (nT2 - 1); + + nAV1 = (sFrmDifAvgRat * nAV11 + (32 - sFrmDifAvgRat) * nAV12); + nAV1 = ((nAV1 + 16) >> 5); + + /* for Mit32VHLine */ + if (nDif02[HISDIFNUM-1] > nDif02[HISDIFNUM-6]) + nFlgChk1 = nDif02[HISDIFNUM-1] - nDif02[HISDIFNUM-6]; + else + nFlgChk1 = nDif02[HISDIFNUM-6] - nDif02[HISDIFNUM-1]; + + /* if (pFlg32[HISDETNUM-1] == 4) { */ + /* B-B A-A-A X-Y-Z */ + /* ---------=>Sceen changed */ + if (pFlg32[HISDETNUM-1] == 4 || pFlg32[HISDETNUM-1] == 5) { + nFlgChk3 = nFlgChk1; + for (nT0 = 2; nT0 <= 5; nT0++) { + nFlgChk2 = nDif02[HISDIFNUM-nT0] + - nDif02[HISDIFNUM-nT0-5]; + if (nFlgChk2 < 0) + nFlgChk2 = -nFlgChk2; + + /* 5-loop: maximum */ + if (nFlgChk2 > nFlgChk3) + nFlgChk3 = nFlgChk2; + } + nFlgChk3 = 16 * nFlgChk3 / nAV1; + } else + nFlgChk3 = 255; + /* for Mit32VHLine */ + + if (pFlg32[HISDETNUM - 1] == 2 || pFlg32[HISDETNUM - 1] == 4 + || pFlg32[HISDETNUM - 1] == 3) { + /* ========================================== */ + if (nDif02[HISDIFNUM - 2] > nDif02[HISDIFNUM - 7]) + nFlgChk2 = + nDif02[HISDIFNUM - 2] - nDif02[HISDIFNUM - 7]; + else + nFlgChk2 = + nDif02[HISDIFNUM - 7] - nDif02[HISDIFNUM - 2]; + + if (nFlgChk1 > nFlgChk2) + nFlgChk2 = nFlgChk1 - nFlgChk2; + else + nFlgChk2 = nFlgChk2 - nFlgChk1; + + nFlgChk2 = 16 * nFlgChk2 / nAV1; + /* ============================================ */ + + /* please check the DI-skateboard */ + /* the next should be 1 and 3 */ + /* dif02(flg=2 vs 1) almost same */ + /* dif02(flg=4 vs 3) almost same */ + if (nDif02[HISDIFNUM - 1] > nDif02[HISDIFNUM - 2]) + nFlgChk1 = + nDif02[HISDIFNUM - 1] - nDif02[HISDIFNUM - 2]; + else + nFlgChk1 = + nDif02[HISDIFNUM - 2] - nDif02[HISDIFNUM - 1]; + + nFlgChk1 = 16 * nFlgChk1 / nAV1; + + if (prt_flg) + sprintf(debug_str + strlen(debug_str), + "nFlgChk1/2/3=(%2d,%2d,%02d)\n", + nFlgChk1, nFlgChk2, nFlgChk3); + } else { + nFlgChk1 = 0; + nFlgChk2 = 0; + } + /* ============================================= */ + + nT2 = 5 * nDif02[HISDIFNUM - 1] / (nMn + sFrmDifLgTDif + 1); + nT2 = nT2>>1; + if (nMn <= (1 << flm32_f2fdif_min0)) { + nSTP = nT2; + } else { + nSTP = + 16 * (nDif02[HISDIFNUM - 1] - nMn) + (nAV1 - nMn + + sFrmDifLgTDif) / 2; + nSTP = nSTP / (nAV1 - nMn + sFrmDifLgTDif); + + /* ======================== */ + /* patch for DI1 3:2, [ 16 16 9 16 0] */ + if (nT2 > nSTP) + nSTP = nT2; + /* ======================== */ + } + + if (nSTP > 16) + nSTP = 16; + + for (nT0 = 1; nT0 < HISDETNUM; nT0++) { + pFlm02[nT0 - 1] = pFlm02[nT0]; + pFlm02t[nT0 - 1] = pFlm02t[nT0]; + } + + if (nDif02[HISDIFNUM - 1] > (nMn + sFrmDifLgTDif) * sF32DifLgRat) { + pFlm02t[HISDETNUM - 1] = + nDif02[HISDIFNUM - 1] / (nMn + sFrmDifLgTDif); + } else { + pFlm02t[HISDETNUM - 1] = nSTP; + } + + pFlm02[HISDETNUM - 1] = nSTP; + + /* -------------------------------- */ + nMn = pFlm02[HISDETNUM - 1]; + nMIX = 5; + for (nT0 = 0; nT0 < 6; nT0++) { + nFlg02[5 - nT0] = pFlm02[HISDETNUM - 1 - nT0]; + if (nFlg02[5 - nT0] < nMn && nT0 <= 4) { + nMn = nFlg02[5 - nT0]; + nMIX = 5 - nT0; + } + } + nFlg02[nMIX] = 16 - nFlg02[nMIX]; + if (nMIX == 5) + nFlg02[0] = 16 - nFlg02[0]; + + /* -------------------------------------------- */ + /* field difference */ + /* pFlm01 */ + /* length of pFlm01/nDif01: [0:5]; */ + /* iDx: index of minimum dif02 ([0:5] */ + Cal32Flm01(pFlm01, nDif01, nMIX, pPar); + for (nT0 = 0; nT0 < 6; nT0++) { + if ((nT0 == FIX02[0][nMIX - 1]) || (nT0 == FIX02[1][nMIX - 1])) + nFlg01[nT0] = pFlm01[HISDETNUM - 6 + nT0]; + else + nFlg01[nT0] = 16 - pFlm01[HISDETNUM - 6 + nT0]; + } + + if (FIX02[0][nMIX - 1] == 5 || FIX02[1][nMIX - 1] == 5) + nFlg01[0] = pFlm01[HISDETNUM - 6]; + + /* A-A-A B-B C-C-C D-D E-E-E */ + /* 0-1-1 0-0 0-1-1 0-0 */ + for (nT0 = 0; nT0 < 6; nT0++) { + + if (nMIX == 1 && nT0 == 5) { + nSTP = + sF32StpWgt02 * nFlg02[nT0] + (16 - + sF32StpWgt02) * + nFlg01[nT0]; + } else if (nMIX == 5 && nT0 == 0) { + nSTP = + sF32StpWgt02 * nFlg02[nT0] + (16 - + sF32StpWgt02) * + nFlg01[nT0]; + } else if (nT0 == nMIX || nT0 == nMIX - 1) { + nSTP = + sF32StpWgt02 * nFlg02[nT0] + (16 - + sF32StpWgt02) * + nFlg01[nT0]; + } else { + nSTP = + sF32StpWgt01 * nFlg01[nT0] + (16 - + sF32StpWgt02) * + nFlg02[nT0]; + } + + nFlg12[nT0] = ((nSTP + 8) >> 4); + } + /* -------------------------------------------- */ + + /* -------------------------------------------- */ + Flm32DetSub1(pRDat, nFlg12, pFlm02t, nFlg01, nFlg02, nMIX); + /* -------------------------------------------- */ + + /* 150213-patch */ + nSTP = pRDat->pFrm32[HISDETNUM - 6 + nMIX]; + for (nT1 = 5; nT1 > 0; nT1--) { + if (nT1 != nMIX) + nSTP += (16 - pRDat->pFrm32[HISDETNUM - 6 + nT1]); + } + + if (nMn < (1 << flm32_f2fdif_min1) && nSTP <= 2) { + nSTP = 0; + for (nT1 = 4; nT1 >= 0; nT1--) { + if (sFld32[nT1] >= pRDat->pFld32[HISDETNUM - 6 + nT1]) { + nSTP += + (sFld32[nT1] - + pRDat->pFld32[HISDETNUM - 6 + nT1]); + } else { + nSTP += + (pRDat->pFld32[HISDETNUM - 6 + nT1] - + sFld32[nT1]); + } + } + + if (nSTP <= 2) { + pRDat->pMod32[HISDETNUM - 1] = 3; + pRDat->pFlg32[HISDETNUM - 1] = nMIX; + } + } + + for (nT1 = 1; nT1 <= 5; nT1++) + sFld32[nT1 - 1] = sFld32[nT1]; + + sFld32[5] = pRDat->pFld32[HISDETNUM - 5]; + /* -------------------------------------------- */ + + /* ============================================= */ + /* please check the DI-skateboard */ + /* the next should be 1 and 3 */ + /* dif02(flg=2 vs 1) almost same */ + /* dif02(flg=4 vs 3) almost same */ + /* nFlgChk3: for Mit32VHLine */ + /* last: for sceen change */ + if (((nFlgChk1 > flm32_chk1_rtn) && + (nFlgChk3 > flm32_ck13_rtn)) + || (nFlgChk2 > flm32_chk2_rtn) + || ((pFlg32[HISDETNUM-1] == 4) && + (nFlgChk3 > flm32_chk3_rtn))) { + pRDat->pMod32[HISDETNUM - 1] = 0; + pRDat->pFlg32[HISDETNUM - 1] = 0; + + if (prt_flg) + sprintf(debug_str + strlen(debug_str), + "Reg: ck1=%d, ck13=%d, ck2=%d, ck3=%d\n", + flm32_chk1_rtn, flm32_ck13_rtn, + flm32_chk2_rtn, flm32_chk3_rtn); + } + /* ============================================= */ + + if (prt_flg) { + sprintf(debug_str + strlen(debug_str), + "Mod=%d, Flg=%d, Num=%3d\n", + pRDat->pMod32[HISDETNUM - 1], + pRDat->pFlg32[HISDETNUM - 1], + pRDat->mNum32[HISDETNUM - 1]); + pr_info("%s", debug_str); + } + + return 0; +} + +/* length of pFlm01/nDif01: [0:5]; */ +/* iDx: index of minimum dif02 ([0:5] */ +int Cal32Flm01(UINT8 *pFlm01, int *nDif01, int iDx, + struct sFlmSftPar *pPar) +{ + int sF32Dif01A1 = pPar->sF32Dif01A1; /* 65; */ + int sF32Dif01T1 = pPar->sF32Dif01T1; /* 128; */ + + int sF32Dif01A2 = pPar->sF32Dif01A2; /* 65; */ + int sF32Dif01T2 = pPar->sF32Dif01T2; /* 128; */ + + int dDif05[5]; /* patch for MIT32-Line */ + + int nT0 = 0; + int nT1 = 0; + /* int nT2=0; */ + int nSP = 0; + + int CP = nDif01[HISDIFNUM - 1]; /* Last */ + int PP = nDif01[HISDIFNUM - 2]; /* Prev */ + + int nMn = ((CP < PP) ? CP : PP); + int nMx = ((CP > PP) ? CP : PP); + + for (nT0 = 0; nT0 < HISDETNUM - 1; nT0++) + pFlm01[nT0] = pFlm01[nT0 + 1]; + + nSP = nDif01[HISDIFNUM-1]; + for (nT0 = 0; nT0 < 5; nT0++) { + if (nDif01[HISDIFNUM-1-nT0] >= nDif01[HISDIFNUM-6-nT0]) + dDif05[nT0] = nDif01[HISDIFNUM-1-nT0] + - nDif01[HISDIFNUM-6-nT0]; + else + dDif05[nT0] = nDif01[HISDIFNUM-6-nT0] + - nDif01[HISDIFNUM-1-nT0]; + + if (nDif01[HISDIFNUM-1-nT0] < nSP) + nSP = nDif01[HISDIFNUM-1-nT0]; + } + + for (nT0 = 0; nT0 < 5; nT0++) + dDif05[nT0] = 8 * dDif05[nT0] / (nSP + 1024); + + + if (iDx == 5) { + /* Last three */ + if (nDif01[HISDIFNUM - 3] > nMx) + nMx = nDif01[HISDIFNUM - 3]; + + if (nDif01[HISDIFNUM - 3] < nMn) + nMn = nDif01[HISDIFNUM - 3]; + + nSP = 16 * (CP - nMn) + (nMx - nMn) / 2; + nSP = nSP / (nMx - nMn + 1); + if (nSP > 16) + nSP = 16; + + pFlm01[HISDETNUM - 1] = nSP; + } else if (iDx == 4) { + nT0 = sF32Dif01T1 + ((CP * sF32Dif01A1 + 32) >> 6); /* x/64 */ + nT1 = sF32Dif01T1 + ((PP * sF32Dif01A1 + 32) >> 6); /* x/64 */ + + if (nT0 <= PP) { + pFlm01[HISDETNUM - 1] = 0; + pFlm01[HISDETNUM - 2] = 16; + } else if (nT1 <= CP) { + pFlm01[HISDETNUM - 2] = 0; + pFlm01[HISDETNUM - 1] = 16; + } else { + pFlm01[HISDETNUM - 2] = 8; /* overlap */ + pFlm01[HISDETNUM - 1] = 8; /* overlap */ + } + } else { + nT0 = sF32Dif01T2 + ((CP * sF32Dif01A2 + 32) >> 6); /* x/64 */ + nT1 = sF32Dif01T2 + ((PP * sF32Dif01A2 + 32) >> 6); /* x/64 */ + + if (nT0 <= PP) + pFlm01[HISDETNUM - 1] = 0; + else if (nT1 <= CP) + pFlm01[HISDETNUM - 1] = 16; + else + pFlm01[HISDETNUM - 1] = 8; /* overlap */ + } + + nSP = dDif05[0]; + for (nT0 = 1; nT0 < 5; nT0++) { + if (nSP < dDif05[nT0]) + nSP = dDif05[nT0]; /* maximum */ + } + if (nSP <= 3) { + if (iDx == 2) { + pFlm01[HISDETNUM-1] = 16; + pFlm01[HISDETNUM-2] = 0; + } else if (iDx == 1) { + pFlm01[HISDETNUM-1] = 0; + pFlm01[HISDETNUM-2] = 16; + } + } + + return 0; +} + +/* length: [0:5] */ +/* MIX: [1~5] */ +int Flm32DetSub1(struct sFlmDatSt *pRDat, UINT8 *nFlg12, UINT8 *pFlm02t, + UINT8 *nFlg01, UINT8 *nFlg02, UINT8 MIX) +{ + UINT8 *pFlg = pRDat->pFlg32; + UINT8 *pMod = pRDat->pMod32; + + int CFg = pFlg[HISDETNUM - 1]; + int RFlg[5] = { 5, 1, 2, 3, 4 }; + int nT0 = 0; + int CNT = 0; + + UINT8 MN0 = nFlg12[5]; + UINT8 MN1 = nFlg01[5]; + UINT8 MN2 = nFlg02[5]; + + int ID0 = 0; + int ID1 = 0; + + for (nT0 = 5; nT0 >= 0; nT0--) { + if (pMod[nT0] == 3) + CNT++; + else + break; + } + + for (nT0 = 0; nT0 < HISDETNUM - 1; nT0++) { + pMod[nT0] = pMod[nT0 + 1]; + pFlg[nT0] = pFlg[nT0 + 1]; + } + + for (nT0 = 0; nT0 < 5; nT0++) { + if (nFlg12[nT0] < MN0) + MN0 = nFlg12[nT0]; + + if (nFlg01[nT0] < MN1) + MN1 = nFlg01[nT0]; + + if (nFlg02[nT0] < MN2) + MN2 = nFlg02[nT0]; + } + + if (CFg == 0 && MN0 >= 10 && MN1 >= 10 && MN2 >= 10) { + pMod[HISDETNUM - 1] = 3; + pFlg[HISDETNUM - 1] = MIX; + } else if (CFg != 0 && RFlg[CFg - 1] == MIX && MN0 >= 8) { + pMod[HISDETNUM - 1] = 3; + pFlg[HISDETNUM - 1] = MIX; + if (CNT <= 2 && (MN1 <= 8 || MN2 <= 8)) + pFlg[HISDETNUM - 1] = 0; + } else { + pMod[HISDETNUM - 1] = 0; + pFlg[HISDETNUM - 1] = 0; + + MN0 = pFlm02t[HISDETNUM - 1]; + MN1 = pFlm02t[HISDETNUM - 1]; + ID0 = 5; + ID1 = 5; + for (nT0 = 4; nT0 >= 1; nT0--) { + if (pFlm02t[HISDETNUM - 6 + nT0] < MN0) { + MN1 = MN0; + ID1 = ID0; + MN0 = pFlm02t[HISDETNUM - 6 + nT0]; + ID0 = nT0; + } else if (pFlm02t[HISDETNUM - 6 + nT0] < MN1) { + MN1 = pFlm02t[HISDETNUM - 6 + nT0]; + ID1 = nT0; + } + } + + MIX = ID0; + if (ID0 == 5 && ID1 == 5) { + if (pFlm02t[HISDETNUM - 6] > MN0) + MN0 = pFlm02t[HISDETNUM - 6]; + + CNT = 0; + for (nT0 = 1; nT0 <= 4; nT0++) { + if (pFlm02t[HISDETNUM - 6 + nT0] > + (MN0 + 2) * 32) { + CNT++; + } + } + + if (CNT == 4) { + if (CFg == 0) { + pMod[HISDETNUM - 1] = 3; + pFlg[HISDETNUM - 1] = MIX; + } else if (RFlg[CFg - 1] == MIX) { + pMod[HISDETNUM - 1] = 3; + pFlg[HISDETNUM - 1] = MIX; + } + } + } else if (MN1 > (MN0 + 2) * 32) { + /* All >64 */ + if (ID0 != 5) { + if (CFg == 0) { + pMod[HISDETNUM - 1] = 3; + pFlg[HISDETNUM - 1] = MIX; + } else if (RFlg[CFg - 1] == MIX) { + pMod[HISDETNUM - 1] = 3; + pFlg[HISDETNUM - 1] = MIX; + } + } /* if(ID0!=5) */ + } /* if(MN1>(MN0+2)*32) */ + } + + return 0; +} + +/* Film2-2 Detection */ +int Flm22DetSft(struct sFlmDatSt *pRDat, int *nDif02, + int *nDif01, struct sFlmSftPar *pPar) +{ + UINT8 *pFlg = pRDat->pFlg22; + UINT8 *pMod = pRDat->pMod22; + + UINT8 *pStp = pRDat->pStp22; + UINT8 *pSmp = pRDat->pSmp22; + UINT8 *mNum22 = pRDat->mNum22; + + int sFlm2MinAlpha = pPar->sFlm2MinAlpha; /* 32; // [0~63] */ + int sFlm2MinBelta = pPar->sFlm2MinBelta; /* 32; // [0~63] */ + int sFlm20ftAlpha = pPar->sFlm20ftAlpha; /* 16; // [0~63] */ + int sFlm2LgDifThd = pPar->sFlm2LgDifThd; /* 4096; */ + int sFlm2LgFlgThd = pPar->sFlm2LgFlgThd; /* 8; */ + + int cFlg = pFlg[HISDETNUM - 1]; + int rFlg[4] = { 2, 3, 4, 1 }; + + int nT0 = 0; + int nT1 = 0; + int CNT0 = 0; + int CNT1 = 0; + + int nMn = nDif01[HISDIFNUM - 1]; + int nMx = nDif01[HISDIFNUM - 1]; + + int nSM20 = nDif01[HISDIFNUM - 1]; + int nSM21 = 0; + int nSM22 = 0; + int nL21 = 0; + int nL22 = 0; + int Mx56 = 0; + int Mn56 = 0; + + int nAV20 = 0; + int nAV21 = 0; + int nAV22 = 0; + int nOfst = 0; + int tMgn = 0; + int BtMn = 0; + + int FdTg[6]; + + int nFlgChk1 = 0; /* chk1 */ + int nFlgCk20 = 0; /* chk2-0 */ + int nFlgCk21 = 0; /* chk2-1 */ + int nFlgChk3 = 0; /* chk3 */ + int nFlgChk4 = 0; /* chk4 */ + int nFlgChk5 = 0; /* chk5 */ + int nFlgChk6 = 0; /* dif02-small */ + + static UINT8 nCk20Cnt; + static UINT8 nCk21Cnt; + /* check 2-2: for panda sequence */ + /* static UINT8 nCk22Flg[HISDETNUM]; */ + /* static UINT8 nCk22Cnt; */ + + /* size of image */ + int iWidth = pRDat->iWidth; + int iHeight = pRDat->iHeight; + int nFlm22Lvl = 0; + int nSIZE = iWidth * iHeight + 1; + + prt_flg = ((pr_pd >> 3) & 0x1); + if (prt_flg) + sprintf(debug_str, "#Dbg22:\n"); + + for (nT0 = 0; nT0 < HISDETNUM - 1; nT0++) { + pFlg[nT0] = pFlg[nT0 + 1]; + pMod[nT0] = pMod[nT0 + 1]; + pStp[nT0] = pStp[nT0 + 1]; + pSmp[nT0] = pSmp[nT0 + 1]; + /* nCk22Flg[nT0] = nCk22Flg[nT0+1]; */ + } + + /* ========== check1/3 2-2 mode ========== */ + /* |dif02(t-1) - dif02(t-0)| => should be small */ + /* |dif01(t-1) - (dif01(t)+dif02(t))| => should be small */ + nFlgChk1 = 0; + nFlgChk3 = 0; + nAV20 = 0; + if (pFlg[HISDETNUM-1] == 0) { + nFlgChk1 = 255; + nFlgChk3 = 255; + nFlgChk4 = 0; + /* nCk22Cnt = 0; */ + } else if (pFlg[HISDETNUM-1] == 2 + || pFlg[HISDETNUM-1] == 4) { + for (nT0 = 1; nT0 <= 7; nT0 = nT0+2) { + if (nDif02[HISDIFNUM-nT0] > nDif02[HISDIFNUM-nT0-1]) { + nOfst = nDif02[HISDIFNUM-nT0] + - nDif02[HISDIFNUM-nT0-1]; + nAV20 = nAV20 + nDif02[HISDIFNUM-nT0-1]; + } else { + nOfst = nDif02[HISDIFNUM-nT0-1] + - nDif02[HISDIFNUM-nT0]; + nAV20 = nAV20 + nDif02[HISDIFNUM-nT0]; + } + + /* maximum */ + if (nOfst > nFlgChk1) + nFlgChk1 = nOfst; + + tMgn = nDif02[HISDIFNUM-nT0]+nDif01[HISDIFNUM-nT0]; + if (tMgn > nDif01[HISDIFNUM-nT0-1]) + BtMn = tMgn - nDif01[HISDIFNUM-nT0-1]; + else + BtMn = nDif01[HISDIFNUM-nT0-1] - tMgn; + + if (BtMn > nFlgChk3) + nFlgChk3 = BtMn; + + } + nAV20 = nAV20>>2; + nFlgChk1 = 16*nFlgChk1/(nAV20+1024); + nFlgChk3 = 16*nFlgChk3/(nAV20+1024); + if (nAV20 < (nSIZE >> flm22_stl_sft)) + mNum22[HISDETNUM-1] = 0; /* static sequence */ + + if (prt_flg) + sprintf(debug_str + strlen(debug_str), + "nAV20(%04d) < (%04d)\n", + nAV20, (nSIZE >> flm22_stl_sft)); + } else { + nFlgChk1 = 0; + nFlgChk3 = 0; + + for (nT0 = 1; nT0 <= 8; nT0 = nT0 + 2) { + if (nDif02[HISDIFNUM-nT0] > nDif01[HISDIFNUM-nT0]) + nFlgChk4++; + } + } + /* ========== check1/3 2-2 mode ========== */ + + for (nT0 = 2; nT0 <= 4; nT0++) { + nT1 = nDif01[HISDIFNUM - nT0]; + + nSM20 += nT1; + + if (nMx < nT1) + nMx = nT1; + + if (nMn > nT1) + nMn = nT1; + } + /* sum(0~5), last-6 */ + nSM20 += (nDif01[HISDIFNUM - 5] + nDif01[HISDIFNUM - 6]); + nAV20 = (nSM20 - nMx + 2) / 5; + + nFlgChk6 = 0; + for (nT0 = 1; nT0 <= 6; nT0++) { + nT1 = nDif01[HISDIFNUM - nT0]; + if (nT1 >= nAV20) { + nL21 += 1; + nSM21 += nT1; + } + + if (nT1 <= nAV20) { + nL22 += 1; + nSM22 += nT1; + } + nFlgChk6 += (nDif02[HISDIFNUM-nT0] >> 8); + } + nFlgChk6 = nFlgChk6 / 6; + + nAV21 = (nSM21 + nL21 / 2) / nL21; /* High average */ + nAV22 = (nSM22 + nL22 / 2) / nL22; /* Low average */ + nOfst = nAV21 - nAV22; + + if (prt_flg) + sprintf(debug_str + strlen(debug_str), + "LAvg=%04d\n", (nAV22/nSIZE)); + + if (nAV22 > (nSIZE << 3)) + mNum22[HISDETNUM - 1] = 0; + else if (nAV22 > (nSIZE * flm22_lavg_lg >> 3)) + mNum22[HISDETNUM - 1] = 0; + + /* ========== check2 2-2 mode ========== */ + /* |dif01(t-0) - dif01(t-2)| => should be small */ + /* |dif01(t-0) - dif01(t-4)| => should be small */ + nFlgCk20 = 0; + nFlgCk21 = 0; + for (nT0 = 1; nT0 <= 4; nT0++) { + nOfst = nDif01[HISDIFNUM-nT0] - nDif01[HISDIFNUM-nT0-2]; + if (nOfst < 0) + nOfst = -nOfst; + if (nOfst > nFlgCk20) /* maximum */ + nFlgCk20 = nOfst; + + nOfst = nDif01[HISDIFNUM-nT0] - nDif01[HISDIFNUM-nT0-4]; + if (nOfst < 0) + nOfst = -nOfst; + if (nOfst > nFlgCk21) /* maximum */ + nFlgCk21 = nOfst; + } + nFlgCk20 = 16*nFlgCk20/(nAV22+1024); + nFlgCk21 = 16*nFlgCk21/(nAV22+1024); + + if (nFlgCk20 < flm22_chk20_sml) { + if (nCk20Cnt < 255) + nCk20Cnt++; + } else + nCk20Cnt = 0; + + if (nFlgCk21 < flm22_chk21_sml) { + if (nCk21Cnt < 255) + nCk21Cnt++; + } else + nCk21Cnt = 0; + + /* ========== check2 2-2 mode ========== */ + + /* ------------------------------ */ + /* Max or min of (5/6) */ + if (nDif01[HISDIFNUM - 1] > nDif01[HISDIFNUM - 2]) { + Mx56 = nDif01[HISDIFNUM - 1]; + Mn56 = nDif01[HISDIFNUM - 2]; + } else { + Mx56 = nDif01[HISDIFNUM - 2]; + Mn56 = nDif01[HISDIFNUM - 1]; + } + /* ------------------------------ */ + + CNT0 = 0; + for (nT0 = 5; nT0 >= 0; nT0--) { + if (pMod[HISDETNUM - 6 + nT0] == 2) + CNT0++; + else + break; + } + + if (CNT0 >= 1) { + sFlm20ftAlpha = sFlm20ftAlpha - ((CNT0 * 25 + 8) >> 4); + sFlm2MinBelta = sFlm2MinBelta - ((CNT0 * 36 + 8) >> 4); + } + + /* water girl: part-2 */ + if (nCk21Cnt < flm22_chk21_sm2) { + nT0 = sFlm2MinAlpha*Mn56+sFlm20ftAlpha*nOfst; + tMgn = ((nT0+16)>>5); + + nT1 = sFlm2MinBelta*Mn56; + BtMn = ((nT1+32)>>6); + + /* ----------------------------------- */ + /* int *pStp = pRDat->pStp22; */ + /* int *pSmp = pRDat->pSmp22; */ + nT0 = 16*(Mx56-tMgn) + (BtMn+sFlm2LgDifThd)/2; + nT1 = nT0/(BtMn+sFlm2LgDifThd); + if (nT1 > 16) + nT1 = 16; + else if (nT1 < 0) + nT1 = 0; + } else { + nT1 = 16; + } + + pStp[HISDETNUM - 1] = nT1; + if (Mx56 == nDif01[HISDIFNUM - 1]) + pSmp[HISDETNUM - 1] = 1; + else + pSmp[HISDETNUM - 1] = 0; + + /* ------------------------------------ */ + CNT0 = 0; + CNT1 = 0; + for (nT0 = 0; nT0 < 6; nT0++) { + if (pStp[HISDETNUM - 6 + nT0] >= sFlm2LgFlgThd) { + FdTg[CNT0] = nT0; + CNT0++; + } + CNT1 += pSmp[HISDETNUM - 6 + nT0]; + } + + nT0 = 0; + nT1 = 0; + nFlgChk5 = 0; + if (CNT0 == 6 && CNT1 == 3) { + if (pSmp[HISDETNUM - 6] && pSmp[HISDETNUM - 4] && + pSmp[HISDETNUM - 2]) { + nT1 = 2; + if (cFlg != 0) { + if (cFlg % 2 == 0) + nT0 = rFlg[cFlg - 1]; + } else { + nT0 = 1; + } + } else if (pSmp[HISDETNUM - 5] && pSmp[HISDETNUM - 3] && + pSmp[HISDETNUM - 1]) { /* All 1 */ + nT1 = 2; + if (cFlg != 0) { + if (cFlg % 2 == 1) + nT0 = rFlg[cFlg - 1]; + } else { + nT0 = 4; + } + } + + /* --------------------------------------- */ + /* patch for toilet paper */ + /* Low average avg>(totoal*x) x>1 */ + /* tMgn = (nAV22 * 64) >> 8; */ + /* if(tMgn > 720*240) */ + /* if(tMgn > iWidth*iHeight*32) */ /*toilet paper*/ + /* parameter */ + nOfst = nAV21 - nAV22; + if (nAV22 > (nSIZE << flm22_lavg_sft)) /* low average */ + nFlgChk5 = 16; + else if ((nAV22 << 4) > (nSIZE * flm22_chk5_avg)) + nFlgChk5 = nAV22 / nSIZE; + else if (nOfst < ((nAV22 * 46) >> 7)) + nFlgChk5 = (nAV22 << 2) / (nOfst + 32); + + if (nFlgChk5 > 32) + nFlgChk5 = 32; + /* --------------------------------------- */ + + nL22 = (nSIZE >> 9) + 1; + if (nFlgChk6 < nL22) + nFlgChk6 = nL22 / (nFlgChk6 + 1); + else if (nFlgChk6 > (nL22 << 1)) + nFlgChk6 = nFlgChk6 / nL22; + else + nFlgChk6 = 0; + + if (nFlgChk6 > flm22_chk6_max) + nFlgChk6 = flm22_chk6_max; + } + pFlg[HISDETNUM - 1] = nT0; + pMod[HISDETNUM - 1] = nT1; + /* ----------------------------------- */ + + /* for panda */ + /* check bug */ + /* + * if (pFlg[HISDETNUM-1] & 0x1) { + * nCk22Flg[HISDETNUM-1] = nT0; + + * if (nT0 == 0) + * nCk22Cnt = nCk22Cnt+1; + * else + * nCk22Cnt = 0; + + * if (nCk22Cnt > 254) + * nCk22Cnt = 254; + * } + */ + + /* debug 2-2 mode */ + /* if(pr_pd && (nT0 != 0) && pFlg[HISDETNUM-1]!=0) { */ + if (prt_flg && (pFlg[HISDETNUM-1] & 0x1)) { + if (nT0 != 0) { + sprintf(debug_str + strlen(debug_str), + "nCk1/3/4=(%2d,%2d,%2d)\n", + nFlgChk1, nFlgChk3, nFlgChk4); + sprintf(debug_str + strlen(debug_str), + "nCk20/1Cnt=(%2d,%2d)\n", + nCk20Cnt, nCk21Cnt); + } + } + + /* ========== check2 2-2 mode ========== */ + nFlm22Lvl = (mNum22[HISDETNUM-1] >> 2); + if (nFlm22Lvl > 64) + nFlm22Lvl = 64; + + /* panda */ + /* if (pFlg[HISDETNUM-1] && nCk22Cnt < 20) */ + /* nFlm22Lvl = nFlm22Lvl + nCk22Cnt - 20; */ + + /* 2-2 but with combing: force dejaggies */ + /* return information */ + if (nFlgChk1 < flm22_anti_chk1) { + nT1 = ((flm22_anti_chk1 - nFlgChk1) >> 2); + nFlm22Lvl += nT1; + } + + nT1 = ((nCk20Cnt > nCk21Cnt) ? nCk20Cnt : nCk21Cnt); + if (nT1 > 128) + nT1 = 128; + nT1 = ((nT1 + 4) >> 3); + nFlm22Lvl += nT1; + + if (nFlgChk3 < flm22_anti_chk3) { + nT1 = ((flm22_anti_chk3 - nFlgChk3) >> 3); + nFlm22Lvl += nT1; + } + + if (nFlgChk4 < flm22_anti_chk4) { + nT1 = ((flm22_anti_chk4 - nFlgChk4) >> 3); + nFlm22Lvl += nT1; + } + + /* for sony-mp3 */ + if (flm22_anti_ck141 < flm22_anti_ck140) + flm22_anti_ck141 = flm22_anti_ck140; + nT0 = flm22_anti_ck141 - flm22_anti_ck140; + + if ((nFlgChk1 > flm22_anti_ck140) || + (nFlgChk4 > flm22_anti_ck141)) { + if (nFlgChk1 > (nFlgChk4 + nT0)) + nT1 = nFlgChk1 - flm22_anti_ck140; + else + nT1 = nFlgChk4 - flm22_anti_ck141; + + if (nT1 > 128) + nT1 = 128; + + nT1 = (nT1>>2); + + nFlm22Lvl -= nT1; + } + /* for sony-mp3 */ + + nFlm22Lvl -= nFlgChk5; + nFlm22Lvl -= nFlgChk6; + + if (nFlm22Lvl < 0) + nFlm22Lvl = 0; + + if (prt_flg) { + sprintf(debug_str + strlen(debug_str), + "Mod=%d, Flg=%d, Num=%3d, Lvl=%3d\n", + pMod[HISDETNUM - 1], pFlg[HISDETNUM - 1], + mNum22[HISDETNUM-1], nFlm22Lvl); + + pr_info("%s", debug_str); + } + + return nFlm22Lvl; +} diff --git a/drivers/amlogic/media/deinterlace/film_vof_soft.h b/drivers/amlogic/media/deinterlace/film_vof_soft.h new file mode 100644 index 000000000000..9f58ad325c9c --- /dev/null +++ b/drivers/amlogic/media/deinterlace/film_vof_soft.h @@ -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 diff --git a/drivers/amlogic/media/deinterlace/flm_mod_xx.c b/drivers/amlogic/media/deinterlace/flm_mod_xx.c new file mode 100644 index 000000000000..8a6b258b0a71 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/flm_mod_xx.c @@ -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 +#include +#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; +} diff --git a/drivers/amlogic/media/deinterlace/nr.c b/drivers/amlogic/media/deinterlace/nr.c new file mode 100644 index 000000000000..b434283c9be4 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/nr.c @@ -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 +#include +#include +#include +#include +#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); +} + diff --git a/drivers/amlogic/media/deinterlace/nr.h b/drivers/amlogic/media/deinterlace/nr.h new file mode 100644 index 000000000000..1a6f256a12a4 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/nr.h @@ -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 + diff --git a/drivers/amlogic/media/deinterlace/register.h b/drivers/amlogic/media/deinterlace/register.h new file mode 100644 index 000000000000..08c4193e2c9a --- /dev/null +++ b/drivers/amlogic/media/deinterlace/register.h @@ -0,0 +1,4504 @@ +/* + * drivers/amlogic/media/deinterlace/register.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __MACH_DEINTERLACE_REG_ADDR_H_ +#define __MACH_DEINTERLACE_REG_ADDR_H_ + +#define Wr(adr, val) aml_write_vcbus(adr, val) +#define Rd(adr) aml_read_vcbus(adr) +#define Wr_reg_bits(adr, val, start, len) \ + aml_vcbus_update_bits(adr, ((1<>start) + +unsigned int RDMA_WR(unsigned int adr, unsigned int val); +unsigned int RDMA_RD(unsigned int adr); +unsigned int RDMA_WR_BITS(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len); +unsigned int RDMA_RD_BITS(unsigned int adr, unsigned int start, + unsigned int len); +#define VPU_WRARB_REQEN_SLV_L1C1 ((0x2795)) /* << 2) + 0xd0100000) */ +#define VPU_ARB_DBG_STAT_L1C1 ((0x27b4)) /* << 2) + 0xd0100000) */ +#define SRSHARP0_SHARP_SR2_CTRL ((0x3257)) /* << 2) + 0xd0100000) */ +/* Bit 24, sr2_dejaggy_en */ + +#define SRSHARP0_SHARP_DEJ2_MISC ((0x3263)) /* << 2) + 0xd0100000) */ +/* Bit 3 sr2_dejaggy2_alpha_force, + * force enable of the alpha for dejaggy2 + * Bit 2: 0 sr2_dejaggy2_alpha_value, + * forced value of alpha for dejaggy2 + */ + +#define SRSHARP0_DEJ_CTRL 0x3264 /*<< 2) + 0xd0100000)*/ +/* Bit 31:4 reserved + * Bit 3:2, reg_sr3_dejaggy_sameside_prtct + * u2: enable of sr3 dejaggy same side curve protect from filter, + * [0] for proc, [1] for ctrl path, default=3 + * Bit 1, reg_sr3_dejaggy_sameside_mode + * u1: mode of the sameside flag decision: default =1 + * Bit 0, reg_sr3_dejaggy_enable + * u1: enable of sr3 dejaggy: default =0 + */ + +#define SRSHARP0_SHARP_DEJ2_PRC ((0x3261)) /* << 2) + 0xd0100000) */ +/* Bit 31:24, reg_dejaggy2_hcon_thrd : . + * unsigned, default =5,hcon threshold, only pixels with hcon equal or + * larger than this value can be detected as jaggy2 + * Bit 23:16, reg_dejaggy2_svdif_thrd : . unsigned, + * default =30,abs(sum(vdif[4])) threshold to decide jaggy2, only + * pixels ws abs(sum(vdif[4]))>= thrd can be jaggy2 + * Bit 15: 8, reg_dejaggy2_svdif_rate : . + * unsigned, default =32,sum(abs(vdif[4])) <= (rate*abs(sum(vdif[4]))/16) + * rate to decide jaggy2,(normalized 2) + * Bit 7: 6, reserved + * Bit 5: 0, reg_dejaggy2_vdif_thrd : . + * signed, default =-3,vdif threshold for same trend decidion, these value + * is the margin for not same trend; if >0, means need to be same trend, <0, + * can be a little bit glitch + */ +#define SRSHARP0_SHARP_DEJ1_PRC ((0x3262)) /* << 2) + 0xd0100000) */ +/* Bit 31:24, reg_dejaggy1_hcon_thrd : . unsigned, + * default =1,hcon threshold, only pixels with hcon equal or larger + * than this value can be detected as jaggy1 + * Bit 23:16, reg_dejaggy1_svdif_thrd : . unsigned, + * default =50,abs(sum(vdif[4])) threshold to decide jaggy1, only + * pixels ws abs(sum(vdif[4]))<= thrd can be jaggy1 + * Bit 15: 8, reg_dejaggy1_svdif_rate : . unsigned, + * default =64,sum(abs(vdif[4])) <= (rate*abs(sum(vdif[4]))/16) rate + * to decide jaggy2,(normalized 2) + * Bit 7: 6, reserved + * Bit 5: 0, reg_dejaggy1_dif12_rate : . unsigned, + * default =16,sum(abs(vdif2[3]))< (sum(abs(vdif[4]))*rate/32) rate + * to decide jaggy2, (normalized 0.5) + */ +#define SRSHARP0_SHARP_DEJ1_MISC ((0x3264)) /* << 2) + 0xd0100000) */ +/* Bit 31:12, reserved + * Bit 11: 8, reg_dejaggy1_svdif_ofst : . + * unsigned, default =2,sum(abs(vdif[4])) >= (rate*abs(sum(vdif[4]))/32 + ofst) + * offset to decide jaggy2,(normalized 2) + * Bit 7, reg_dejaggy1_proc_chrm : . + * unsigned, default =1, enable to filter 2 pixels step on chroma + * Bit 6, reg_dejaggy1_proc_luma : . + * unsigned, default =1, enable to filter 2 pixels step on luma + * Bit 5: 4, reg_dejaggy1_extend_mode : . + * unsigned, default =3, extend mode for dejaggy1 horizontally, + * 0, no extnd, 1: exend 1 pixel, 2: extend 2 pixels, 3, extend 3 pixels + * Bit 3, reserved + * Bit 2, reg_dejaggy1_alpha_force : . + * unsigned, default =0, force enable of the alpha for dejaggy1 + * Bit 1: 0, reg_dejaggy1_alpha_value : . + * unsigned, default =0, force value of the alpha for dejaggy1 + */ + + + +/* vdin */ +#define VDIN_WR_CTRL 0x1220 +#define WR_CANVAS_BIT 0 +#define WR_CANVAS_WID 8 +/* 0xd0104880 */ +/* Bit 31:30 hconv_mode, Applicable only to bit[13:12]=0 or 2. + * 0: Output every even pixels' CbCr; + * 1: Output every odd pixels' CbCr; + * 2: Output an average value per even&odd pair of pixels; + * 3: Output all CbCr. + * (This does NOT apply to bit[13:12]=0 -- 4:2:2 mode.) + * Bit 29 no_clk_gate: disable vid_wr_mif clock gating function. + * Bit 28 clear write response counter in the vdin write memory interface + * Bit 27 eol_sel, 1: use eol as the line end indication, 0: use width as line + * end indication in the vdin write memory interface + * Bit 26 vcp_nr_en. Only used in VDIN0. NOT used in VDIN1. + * Bit 25 vcp_wr_en. Only used in VDIN0. NOT used in VDIN1. + * Bit 24 vcp_in_en. Only used in VDIN0. NOT used in VDIN1. + * Bit 23 vdin frame reset enble, if true, it will provide frame reset during + * go_field(vsync) to the modules after that + * Bit 22 vdin line fifo soft reset enable, meaning, if true line fifo will + * reset during go_field (vsync) + * Bit 21 vdin direct write done status clear bi + * Bit 20 vdin NR write done status clear bit + * Bit 18 swap_cbcr. Applicable only to bit[13:12]=2. + * 0: Output CbCr (NV12); + * 1: Output CrCb (NV21). + * Bit 17:16 vconv_mode, Applicable only to bit[13:12]=2. 0: Output every even + * lines' CbCr; + * 1: Output every odd lines' CbCr; + * 2: Reserved; + * 3: Output all CbCr. + * Bit 13:12 vdin write format, + * 0: 4:2:2 to luma canvas, 1: 4:4:4 to luma canvas, + * 2: Y to luma canvas, CbCr to chroma canvas. + * For NV12/21, also define Bit + * 31:30, 17:16, and bit 18. + * Bit 11 vdin write canvas double buffer enable, means the canvas address will + * be latched by vsync before using + * Bit 10 1: disable ctrl_reg write pulse which will reset internal counter. + * when bit 11 is 1, this bit should be 1. + * Bit 9 vdin write request urgent + * Bit 8 vdin write request enable + * Bit 7:0 Write luma canvas address + */ +/* timerc */ +#define ISA_TIMER_MUX 0x2650 + /* 0xc1109940 */ +#define ISA_TIMERC 0x2653 + /* 0xc110994c */ +#define ISA_TIMERE 0x2655 + /* 0xc1109954 */ +/* vd1 */ +#define VD1_IF0_LUMA_FIFO_SIZE 0x1a63 + /* 0xd010698c */ +#define VD2_IF0_LUMA_FIFO_SIZE 0x1a83 + /* 0xd0106a0c */ +#define VD1_IF0_CANVAS0 0x1a51 + /* 0xd0106944 */ +#define VD1_IF0_CANVAS1 0x1a52 + /* 0xd0106948 */ +#define VD1_IF0_LUMA_X0 0x1a53 + /* 0xd010694c */ +#define VD1_IF0_LUMA_Y0 0x1a54 + /* 0xd0106950 */ +#define VD1_IF0_CHROMA_X0 0x1a55 + /* 0xd0106954 */ +#define VD1_IF0_CHROMA_Y0 0x1a56 + /* 0xd0106958 */ +#define VD1_IF0_RPT_LOOP 0x1a5b + /* 0xd010696c */ +#define VD1_IF0_LUMA0_RPT_PAT 0x1a5c + /* 0xd0106970 */ +#define VD1_IF0_CHROMA0_RPT_PAT 0x1a5d + /* 0xd0106974 */ +#define VIU_OSD1_CTRL_STAT 0x1a10 + /* 0xd0106840 */ +/* afbc */ +#define AFBC_ENABLE ((0x1ae0)) /* << 2) + 0xd0100000) */ +/* Bit 31:1, reserved + * Bit 8, dec_enable unsigned , default = 0 + * Bit 7:1, reserved + * Bit 0, frm_start unsigned , default = 0 + */ +#define AFBC_MODE ((0x1ae1)) /* << 2) + 0xd0100000) */ +/* Bit 31, soft_reset the use as go_field + * Bit 30:28, reserved + * Bit 27:26, rev_mode uns, default = 0 , reverse mode + * Bit 25:24, mif_urgent uns, default = 3 , + * info mif and data mif urgent + * Bit 22:16, hold_line_num + * Bit 15:14, burst_len uns, default = 1, + * 0: burst1 1:burst2 2:burst4 + * Bit 13:8, compbits_yuv uns, default = 0 , + * bit 1:0,: y component bitwidth : 00-8bit 01-9bit 10-10bit + * bit 3:2,: u component bitwidth : 00-8bit 01-9bit 10-10bit + * bit 5:4,: v component bitwidth : 00-8bit 01-9bit 10-10bit + * Bit 7:6, vert_skip_y uns, default = 0 , + * luma vert skip mode : 00-y0y1, 01-y0, 10-y1, 11-(y0+y1)/2 + * Bit 5:4, horz_skip_y uns, default = 0 , + * luma horz skip mode : 00-y0y1, 01-y0, 10-y1, 11-(y0+y1)/2 + * Bit 3:2, vert_skip_uv uns, default = 0 , + * chroma vert skip mode : 00-y0y1, 01-y0, 10-y1, 11-(y0+y1)/2 + * Bit 1:0, horz_skip_uv uns, default = 0 , + * chroma horz skip mode : 00-y0y1, 01-y0, 10-y1, 11-(y0+y1)/2 + */ +#define AFBC_SIZE_IN ((0x1ae2)) /* << 2) + 0xd0100000) */ +/* Bit 31:29, reserved + * Bit 28:16 hsize_in uns, default = 1920 , + * pic horz size in unit: pixel + * Bit 15:13, reserved + * Bit 12:0, vsize_in uns, default = 1080 , + * pic vert size in unit: pixel + */ +#define AFBC_DEC_DEF_COLOR ((0x1ae3)) /* << 2) + 0xd0100000) */ +/* Bit 31:29, reserved + * Bit 29:20, def_color_y uns, default = 0, + * afbc dec y default setting value + * Bit 19:10, def_color_u uns, default = 0, + * afbc dec u default setting value + * Bit 9: 0, def_color_v uns, default = 0, + * afbc dec v default setting value + */ +#define AFBC_CONV_CTRL ((0x1ae4)) /* << 2) + 0xd0100000) */ +/* Bit 31:12, reserved + * Bit 11: 0, conv_lbuf_len uns, default = 256, + * unit=16 pixel need to set = 2^n + */ +#define AFBC_LBUF_DEPTH ((0x1ae5)) /* << 2) + 0xd0100000) */ +/* Bit 31:28, reserved + * Bit 27:16, dec_lbuf_depth uns, default = 128; // unit= 8 pixel + * Bit 15:12, reserved + * Bit 11:0, mif_lbuf_depth uns, default = 128; + */ +#define AFBC_HEAD_BADDR ((0x1ae6)) /* << 2) + 0xd0100000) */ +/* Bit 31:0, mif_info_baddr uns, default = 32'h0; */ +#define AFBC_BODY_BADDR ((0x1ae7)) /* << 2) + 0xd0100000) */ +/* Bit 31:0, mif_data_baddr uns, default = 32'h0001_0000; */ +#define AFBC_SIZE_OUT ((0x1ae8)) /* << 2) + 0xd0100000) */ +/* Bit 31:29, reserved + * Bit 28:16, hsize_out uns, default = 1920 ; unit: 1 pixel + * Bit 15:13, reserved + * Bit 12:0, vsize_out uns, default = 1080 ; unit: 1 pixel + */ +#define AFBC_OUT_YSCOPE ((0x1ae9)) /* << 2) + 0xd0100000) */ +/* Bit 31:29, reserved + * Bit 28:16, out_vert_bgn uns, default = 0 ; // unit: 1 pixel + * Bit 15:13, reserved + * Bit 12:0, out_vert_end uns, default = 1079 ; // unit: 1 pixel + */ +#define AFBC_STAT ((0x1aea)) /* << 2) + 0xd0100000) */ +/* Bit 31:1, reserved + * Bit 0, frm_end_stat uns, frame end status + */ +#define AFBC_VD_CFMT_CTRL ((0x1aeb)) /* << 2) + 0xd0100000) */ +/* Bit 31 it true, disable clock, otherwise enable clock + * Bit 30 soft rst bit + * Bit 28 if true, horizontal formatter use repeating to generete pixel, + * otherwise use bilinear interpolation + * Bit 27:24 horizontal formatter initial phase + * Bit 23 horizontal formatter repeat pixel 0 enable + * Bit 22:21 horizontal Y/C ratio, 00: 1:1, 01: 2:1, 10: 4:1 + * Bit 20 horizontal formatter enable + * Bit 19 if true, always use phase0 while vertical formater, + * meaning always + * repeat data, no interpolation + * Bit 18 if true, disable vertical formatter chroma repeat last line + * Bit 17 veritcal formatter dont need repeat line on phase0, + * 1: enable, 0: disable + * Bit 16 veritcal formatter repeat line 0 enable + * Bit 15:12 vertical formatter skip line num at the beginning + * Bit 11:8 vertical formatter initial phase + * Bit 7:1 vertical formatter phase step (3.4) + * Bit 0 vertical formatter enable + */ +#define AFBC_VD_CFMT_W ((0x1aec)) /* << 2) + 0xd0100000) */ +/* Bit 27:16 horizontal formatter width */ +/* Bit 11:0 vertical formatter width */ +#define AFBC_MIF_HOR_SCOPE ((0x1aed)) /* << 2) + 0xd0100000) */ +/* Bit 31:26, reserved + * Bit 25:16, mif_blk_bgn_h uns, default = 0 ; + * // unit: 32 pixel/block hor + * Bit 15:10, reserved + * Bit 9: 0, mif_blk_end_h uns, default = 59 ; + * // unit: 32 pixel/block hor + */ +#define AFBC_MIF_VER_SCOPE ((0x1aee)) /* << 2) + 0xd0100000) */ +/* Bit 31:28, reserved + * Bit 27:16, mif_blk_bgn_v uns, default = 0 ; + * // unit: 32 pixel/block ver + * Bit 15:12, reserved + * Bit 11: 0, mif_blk_end_v uns, default = 269; + * // unit: 32 pixel/block ver + */ +#define AFBC_PIXEL_HOR_SCOPE ((0x1aef)) /* << 2) + 0xd0100000) */ +/* Bit 31:29, reserved + * Bit 28:16, dec_pixel_bgn_h uns, default = 0 ; + * // unit: pixel + * Bit 15:13, reserved + * Bit 12: 0, dec_pixel_end_h uns, default = 1919 ; // unit: pixel + */ +#define AFBC_PIXEL_VER_SCOPE ((0x1af0)) /* << 2) + 0xd0100000) */ +/* Bit 31:29, reserved + * Bit 28:16, dec_pixel_bgn_v uns, default = 0 ; // unit: pixel + * Bit 15:13, reserved + * Bit 12: 0, dec_pixel_end_v uns, default = 1079 ; // unit: pixel + */ +#define AFBC_VD_CFMT_H ((0x1af1)) /* << 2) + 0xd0100000) */ +/* Bit 12:0 vertical formatter height */ + + +/* viu mux */ +#define VIU_MISC_CTRL0 0x1a06 + /* 0xd0106818 */ +#define VIUB_MISC_CTRL0 0x2006 + /* 0xd0108018 */ +/* txl new add begin */ +#define DI_IF2_GEN_REG 0x2010 +#define DI_IF2_CANVAS0 0x2011 +#define DI_IF2_LUMA_X0 0x2012 +#define DI_IF2_LUMA_Y0 0x2013 +#define DI_IF2_CHROMA_X0 0x2014 +#define DI_IF2_CHROMA_Y0 0x2015 +#define DI_IF2_RPT_LOOP 0x2016 +#define DI_IF2_LUMA0_RPT_PAT 0x2017 +#define DI_IF2_CHROMA0_RPT_PAT 0x2018 +#define DI_IF2_DUMMY_PIXEL 0x2019 +#define DI_IF2_LUMA_FIFO_SIZE 0x201a +#define DI_IF2_RANGE_MAP_Y 0x201b +#define DI_IF2_RANGE_MAP_CB 0x201c +#define DI_IF2_RANGE_MAP_CR 0x201d +#define DI_IF2_GEN_REG2 0x201e +#define DI_IF2_FMT_CTRL 0x201f +#define DI_IF2_FMT_W 0x2020 +#define DI_IF2_URGENT_CTRL 0x2021 +#define DI_IF2_GEN_REG3 0x2022 +/*txl new add end*/ + +/* di */ +#define DI_IF1_URGENT_CTRL (0x20a3) /* << 2 + 0xd0100000*/ +/* bit15, auto enable; bit14, canvas write mode ;7:4, high threshold ;3:0 , + * low threshold for di inp chroma path + * bit31, auto enable; bit30, canvas write mode ;23:20, high threshold ;19:16 , + * low threshold for di inp luma path + */ +#define DI_INP_URGENT_CTRL (0x20a4) /* << 2 + 0xd0100000*/ +/* bit15, auto enable; bit14, canvas write mode ;7:4, high threshold ;3:0 , + * low threshold for di mem chroma path + * bit31, auto enable; bit30, canvas write mode ;23:20, high threshold ;19:16 , + * low threshold for di mem luma path + */ +#define DI_MEM_URGENT_CTRL (0x20a5) /* << 2 + 0xd0100000*/ +/* bit15, auto enable; bit14, canvas write mode ;7:4, high threshold ;3:0 , + * low threshold for di chan2 chroma path + * bit31, auto enable; bit30, canvas write mode ;23:20, high threshold ;19:16 , + * low threshold for di chan2 luma path + */ +#define DI_CHAN2_URGENT_CTRL (0x20a6) /* << 2 + 0xd0100000*/ + +#define DI_PRE_CTRL ((0x1700)) /* << 2) + 0xd0100000) */ +/* bit 31, cbus_pre_frame_rst */ +/* bit 30, cbus_pre_soft_rst */ +/* bit 29, pre_field_num */ +/* bit 27:26, mode_444c422 */ +/* bit 25, di_cont_read_en */ +/* bit 24:23, mode_422c444 */ +/* bit 22, mtn_after_nr */ +/* bit 21:16, pre_hold_fifo_lines */ +/* bit 15, nr_wr_by */ +/* bit 14, use_vdin_go_line */ +/* bit 13, di_prevdin_en */ +/* bit 12, di_pre_viu_link */ +/* bit 11, di_pre_repeat */ +/* bit 10, di_pre_drop_1st */ +/* bit 9, di_buf2_en */ +/* bit 8, di_chan2_en */ +/* bit 7, prenr_hist_en */ +/* bit 6, chan2_hist_en */ +/* bit 5, hist_check_en */ +/* bit 4, check_after_nr */ +/* bit 3, check222p_en */ +/* bit 2, check322p_en */ +/* bit 1, mtn_en */ +/* bit 0, nr_en */ +#define DI_POST_CTRL ((0x1701)) /* << 2) + 0xd0100000) */ +/* bit 31, cbus_post_frame_rst */ +/* bit 30, cbus_post_soft_rst */ +/* bit 29, post_field_num */ +/* bit 21:16, post_hold_fifo_lines */ +/* bit 13, prepost_link */ +/* bit 12, di_post_viu_link */ +/* bit 11, di_post_repeat */ +/* bit 10, di_post_drop_1st */ +/* bit 9, mif0_to_vpp_en */ +/* bit 8, di_vpp_out_en */ +/* bit 7, di_wr_bk_en */ +/* bit 6, di_mux_en */ +/* bit 5, di_blend_en */ +/* bit 4, di_mtnp_read_en */ +/* bit 3, di_mtn_buf_en */ +/* bit 2, di_ei_en */ +/* bit 1, di_buf1_en */ +/* bit 0, di_buf0_en */ +#define DI_POST_SIZE ((0x1702)) /* << 2) + 0xd0100000) */ +/* bit 28:16, vsize1post */ +/* bit 12:0, hsize1post */ +#define DI_PRE_SIZE ((0x1703)) /* << 2) + 0xd0100000) */ +/* bit 28:16, vsize1pre */ +/* bit 12:0, hsize1pre */ +#define DI_EI_CTRL0 ((0x1704)) /* << 2) + 0xd0100000) */ +/* bit 23:16, ei0_filter[2:+] abs_diff_left>filter && + * ...right>filter && ...top>filter && ...bot>filter -> filter + */ +/* bit 15:8, ei0_threshold[2:+] */ +/* bit 3, ei0_vertical */ +/* bit 2, ei0_bpscf2 */ +/* bit 1, ei0_bpsfar1 */ +#define DI_EI_CTRL1 ((0x1705)) /* << 2) + 0xd0100000) */ +/* bit 31:24, ei0_diff */ +/* bit 23:16, ei0_angle45 */ +/* bit 15:8, ei0_peak */ +/* bit 7:0, ei0_cross */ +#define DI_EI_CTRL2 ((0x1706)) /* << 2) + 0xd0100000) */ +/* bit 31:24, ei0_close2 */ +/* bit 23:16, ei0_close1 */ +/* bit 15:8, ei0_far2 */ +/* bit 7:0, ei0_far1 */ +#define DI_NR_CTRL0 ((0x1707)) /* << 2) + 0xd0100000) */ +/* bit 26, nr_cue_en */ +/* bit 25, nr2_en */ +#define DI_NR_CTRL1 ((0x1708)) /* << 2) + 0xd0100000) */ +/* bit 31:30, mot_p1txtcore_mode */ +/* bit 29:24, mot_p1txtcore_clmt */ +/* bit 21:16, mot_p1txtcore_ylmt */ +/* bit 15:8, mot_p1txtcore_crate */ +/* bit 7:0, mot_p1txtcore_yrate */ +#define DI_NR_CTRL2 ((0x1709)) /* << 2) + 0xd0100000) */ +/* bit 29:24, mot_curtxtcore_clmt */ +/* bit 21:16, mot_curtxtcore_ylmt */ +/* bit 15:8, mot_curtxtcore_crate */ +/* bit 7:0, mot_curtxtcore_yrate */ +/* `define DI_NR_CTRL3 8'h0a */ +/* no use */ +/* `define DI_MTN_CTRL 8'h0b */ +/* no use */ +#define DI_MTN_CTRL1 ((0x170c)) /* << 2) + 0xd0100000) */ +/* bit 13 , me enable */ +/* bit 12 , me autoenable */ +/* bit 11:8, mtn_paramtnthd */ +/* bit 7:0, mtn_parafltthd */ +#define DI_BLEND_CTRL ((0x170d)) /* << 2) + 0xd0100000) */ +/* bit 31, blend_1_en */ +/* bit 30, blend_mtn_lpf */ +/* bit 28, post_mb_en */ +/* bit 27, blend_mtn3p_max */ +/* bit 26, blend_mtn3p_min */ +/* bit 25, blend_mtn3p_ave */ +/* bit 24, blend_mtn3p_maxtb */ +/* bit 23, blend_mtn_flt_en */ +/* bit 22, blend_data_flt_en */ +/* bit 21:20, blend_top_mode */ +/* bit 19, blend_reg3_enable */ +/* bit 18, blend_reg2_enable */ +/* bit 17, blend_reg1_enable */ +/* bit 16, blend_reg0_enable */ +/* bit 15:14, blend_reg3_mode */ +/* bit 13:12, blend_reg2_mode */ +/* bit 11:10, blend_reg1_mode */ +/* bit 9:8, blend_reg0_mode */ +/* bit 7:0, kdeint */ +/* `define DI_BLEND_CTRL1 8'h0e */ +/* no use */ +/* `define DI_BLEND_CTRL2 8'h0f */ +/* no use */ +#define DI_ARB_CTRL ((0x170f)) /* << 2) + 0xd0100000) */ +/* bit 31:26, di_arb_thd1 */ +/* bit 25:20, di_arb_thd0 */ +/* bit 19, di_arb_tid_mode */ +/* bit 18, di_arb_arb_mode */ +/* bit 17, di_arb_acq_en */ +/* bit 16, di_arb_disable_clk */ +/* bit 15:0, di_arb_req_en */ +#define DI_BLEND_REG0_X ((0x1710)) /* << 2) + 0xd0100000) */ +/* bit 27:16, blend_reg0_startx */ +/* bit 11:0, blend_reg0_endx */ +#define DI_BLEND_REG0_Y ((0x1711)) /* << 2) + 0xd0100000) */ +#define DI_BLEND_REG1_X ((0x1712)) /* << 2) + 0xd0100000) */ +#define DI_BLEND_REG1_Y ((0x1713)) /* << 2) + 0xd0100000) */ +#define DI_BLEND_REG2_X ((0x1714)) /* << 2) + 0xd0100000) */ +#define DI_BLEND_REG2_Y ((0x1715)) /* << 2) + 0xd0100000) */ +#define DI_BLEND_REG3_X ((0x1716)) /* << 2) + 0xd0100000) */ +#define DI_BLEND_REG3_Y ((0x1717)) /* << 2) + 0xd0100000) */ +#define DI_CLKG_CTRL ((0x1718)) /* << 2) + 0xd0100000) */ +/* bit 31:24, pre_gclk_ctrl no clk gate control. if ==1, + * module clk is not gated (always on). [3] for pulldown,[2] + * for mtn_1,[1] for mtn_0,[0] for nr + * bit 23:16, post_gclk_ctrl no clk gate control. [4] + * for ei_1, [3] for ei_0,[2] for ei_top, [1] for blend_1, [0] for blend_0 + * bit 1, di_gate_all clk shut down. if ==1 , + * all di clock shut down + * bit 0, di_no_clk_gate no clk gate control. + * if di_gated_all==0 and di_no_clk_gate ==1, all di clock is always working. + */ +#define DI_EI_CTRL3 ((0x1719)) /* << 2) + 0xd0100000) */ +/* bit 31, reg_ei_1 */ +/* bit 30, reg_demon_en */ +/* bit 26:24, reg_demon_mux */ +/* bit 23:20, reg_right_win */ +/* bit 19:16, reg_left_win */ +/* bit 7:4, reg_ei_sadm_quatize_margin */ +/* bit 1:0, reg_ei_sad_relative_mode */ +#define DI_EI_CTRL4 ((0x171a)) /* << 2) + 0xd0100000) */ +/* bit 29, reg_ei_caldrt_ambliike2_biasvertical */ +/* bit 28:24, reg_ei_caldrt_addxla2list_drtmax */ +/* bit 22:20, reg_ei_caldrt_addxla2list_signm0th */ +/* bit 19, reg_ei_caldrt_addxla2list_mode */ +/* bit 18:16, reg_ei_signm_sad_cor_rate */ +/* bit 15:12, reg_ei_signm_sadi_cor_rate */ +/* bit 11:6, reg_ei_signm_sadi_cor_ofst */ +/* bit 5:0, reg_ei_signm_sad_ofst */ +#define DI_EI_CTRL5 ((0x171b)) /* << 2) + 0xd0100000) */ +/* bit 30:28, reg_ei_caldrt_cnflcctchk_frcverthrd */ +/* bit 26:24, reg_ei_caldrt_cnflctchk_mg */ +/* bit 23:22, reg_ei_caldrt_cnflctchk_ws */ +/* bit 21, reg_ei_caldrt_cnflctchk_en */ +/* bit 20, reg_ei_caldrt_verfrc_final_en */ +/* bit 19, reg_ei_caldrt_verfrc_retimflt_en */ +/* bit 18:16, reg_ei_caldrt_verftc_eithratemth */ +/* bit 15, reg_ei_caldrt_verfrc_retiming_en */ +/* bit 14:12, reg_ei_caldrt_verfrc_bothratemth */ +/* bit 11:9, reg_ei_caldrt_ver_thrd */ +/* bit 8:4, reg_ei_caldrt_addxla2list_drtmin */ +/* bit 3:0, reg_ei_caldrt_addxla2list_drtlimit */ +#define DI_EI_CTRL6 ((0x171c)) /* << 2) + 0xd0100000) */ +/* bit 31:24, reg_ei_caldrt_abext_sad12thhig */ +/* bit 23:16, reg_ei_caldrt_abext_sad00thlow */ +/* bit 15:8, reg_ei_caldrt_abext_sad12thlow */ +/* bit 6:4, reg_ei_caldrt_abext_ratemth */ +/* bit 2:0, reg_ei_caldrt_abext_drtthrd */ +#define DI_EI_CTRL7 ((0x171d)) /* << 2) + 0xd0100000) */ +/* bit 29, reg_ei_caldrt_xlanopeak_codien */ +/* bit 28:24, reg_ei_caldrt_xlanopeak_drtmax */ +/* bit 23, reg_ei_caldrt_xlanopeak_en */ +/* bit 28:24, reg_ei_caldrt_abext_monotrnd_alpha */ +/* bit 28:24, reg_ei_caldrt_abext_mononum12_thrd */ +/* bit 28:24, reg_ei_caldrt_abext_mononum00_thrd */ +/* bit 28:24, reg_ei_caldrt_abext_sad00rate */ +/* bit 28:24, reg_ei_caldrt_abext_sad12rate */ +/* bit 28:24, reg_ei_caldrt_abext_sad00thhig */ +#define DI_EI_CTRL8 ((0x171e)) /* << 2) + 0xd0100000) */ +/* bit 30:28, reg_ei_assign_headtail_magin */ +/* bit 26:24, reg_ei_retime_lastcurpncnfltchk_mode */ +/* bit 22:21, reg_ei_retime_lastcurpncnfltchk_drtth */ +/* bit 20, reg_ei_caldrt_histchk_cnfid */ +/* bit 19:16, reg_ei_caldrt_histchk_thrd */ +/* bit 15, reg_ei_caldrt_histchk_abext */ +/* bit 14, reg_ei_caldrt_histchk_npen */ +/* bit 13:11, reg_ei_caldrt_amblike2_drtmg */ +/* bit 10:8, reg_ei_caldrt_amblike2_valmg */ +/* bit 7:4, reg_ei_caldrt_amblike2_alpha */ +/* bit 3:0, reg_ei_caldrt_amblike2_drtth */ +#define DI_EI_CTRL9 ((0x171f)) /* << 2) + 0xd0100000) */ +/* bit 31:28, reg_ei_caldrt_hcnfcheck_frcvert_xla_th3 */ +/* bit 27, reg_ei_caldrt_hcnfcheck_frcvert_xla_en */ +/* bit 26:24, reg_ei_caldrt_conf_drtth */ +/* bit 23:20, reg_ei_caldrt_conf_absdrtth */ +/* bit 19:18, reg_ei_caldrt_abcheck_mode1 */ +/* bit 17:16, reg_ei_caldrt_abcheck_mode0 */ +/* bit 15:12, reg_ei_caldrt_abcheck_drth1 */ +/* bit 11:8, reg_ei_caldrt_abcheck_drth0 */ +/* bit 6:4, reg_ei_caldrt_abpnchk1_th */ +/* bit 1, reg_ei_caldrt_abpnchk1_en */ +/* bit 0, reg_ei_caldrt_abpnchk0_en */ +#define DI_EI_CTRL10 ((0x1793)) /* << 2) + 0xd0100000) */ +/* bit 31:28, reg_ei_caldrt_hstrrgchk_drtth */ +/* bit 27:24, reg_ei_caldrt_hstrrgchk_frcverthrd */ +/* bit 23:20, reg_ei_caldrt_hstrrgchk_mg */ +/* bit 19, reg_ei_caldrt_hstrrgchk_1sidnul */ +/* bit 18, reg_ei_caldrt_hstrrgchk_excpcnf */ +/* bit 17:16, reg_ei_caldrt_hstrrgchk_ws */ +/* bit 15, reg_ei_caldrt_hstrrgchk_en */ +/* bit 14:13, reg_ei_caldrt_hpncheck_mode */ +/* bit 12, reg_ei_caldrt_hpncheck_mute */ +/* bit 11:9, reg_ei_caldrt_hcnfcheck_mg2 */ +/* bit 8:6, reg_ei_caldrt_hcnfcheck_mg1 */ +/* bit 5:4, reg_ei_caldrt_hcnfcheck_mode */ +/* bit 3:0, reg_ei_caldrt_hcnfcheck_mg2 */ +#define DI_EI_CTRL11 ((0x179e)) /* << 2) + 0xd0100000) */ +/* bit 30:29, reg_ei_amb_detect_mode */ +/* bit 28:24, reg_ei_amb_detect_winth */ +/* bit 23:21, reg_ei_amb_decide_rppth */ +/* bit 20:19, reg_ei_retime_lastmappncnfltchk_drtth */ +/* bit 18:16, reg_ei_retime_lastmappncnfltchk_mode */ +/* bit 15:14, reg_ei_retime_lastmapvertfrcchk_mode */ +/* bit 13:12, reg_ei_retime_lastvertfrcchk_mode */ +/* bit 11:8, reg_ei_retime_lastpnchk_drtth */ +/* bit 6, reg_ei_retime_lastpnchk_en */ +/* bit 5:4, reg_ei_retime_mode */ +/* bit 3, reg_ei_retime_last_en */ +/* bit 2, reg_ei_retime_ab_en */ +/* bit 1, reg_ei_caldrt_hstrvertfrcchk_en */ +/* bit 0, reg_ei_caldrt_hstrrgchk_mode */ +#define DI_EI_CTRL12 ((0x179f)) /* << 2) + 0xd0100000) */ +/* bit 31:28, reg_ei_drtdelay2_lmt */ +/* bit 27:26, reg_ei_drtdelay2_notver_lrwin */ +/* bit 25:24, reg_ei_drtdelay_mode */ +/* bit 23, reg_ei_drtdelay2_mode */ +/* bit 22:20, reg_ei_assign_xla_signm0th */ +/* bit 19, reg_ei_assign_pkbiasvert_en */ +/* bit 18, reg_ei_assign_xla_en */ +/* bit 17:16, reg_ei_assign_xla_mode */ +/* bit 15:12, reg_ei_assign_nlfilter_magin */ +/* bit 11:8, reg_ei_localsearch_maxrange */ +/* bit 7:4, reg_ei_xla_drtth */ +/* bit 3:0, reg_ei_flatmsad_thrd */ +#define DI_EI_CTRL13 ((0x17a8)) /* << 2) + 0xd0100000) */ +/* bit 27:24, reg_ei_int_drt2x_chrdrt_limit */ +/* bit 23:20, reg_ei_int_drt16x_core */ +/* bit 19:16, reg_ei_int_drtdelay2_notver_cancv */ +/* bit 15:8, reg_ei_int_drtdelay2_notver_sadth */ +/* bit 7:0, reg_ei_int_drtdelay2_vlddrt_sadth */ +#define DI_EI_XWIN0 ((0x1798)) /* << 2) + 0xd0100000) */ +/* bit 27:16, ei_xend0 */ +/* bit 11:0, ei_xstart0 */ +#define DI_EI_XWIN1 ((0x1799)) /* << 2) + 0xd0100000) */ +/* DEINTERLACE mode check. */ +#define DI_MC_REG0_X ((0x1720)) /* << 2) + 0xd0100000) */ +/* bit 27:16, mc_reg0_start_x */ +/* bit 11:0, mc_reg0_end_x */ +#define DI_MC_REG0_Y ((0x1721)) /* << 2) + 0xd0100000) */ +#define DI_MC_REG1_X ((0x1722)) /* << 2) + 0xd0100000) */ +#define DI_MC_REG1_Y ((0x1723)) /* << 2) + 0xd0100000) */ +#define DI_MC_REG2_X ((0x1724)) /* << 2) + 0xd0100000) */ +#define DI_MC_REG2_Y ((0x1725)) /* << 2) + 0xd0100000) */ +#define DI_MC_REG3_X ((0x1726)) /* << 2) + 0xd0100000) */ +#define DI_MC_REG3_Y ((0x1727)) /* << 2) + 0xd0100000) */ +#define DI_MC_REG4_X ((0x1728)) /* << 2) + 0xd0100000) */ +#define DI_MC_REG4_Y ((0x1729)) /* << 2) + 0xd0100000) */ +#define DI_MC_32LVL0 ((0x172a)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mc_reg2_32lvl */ +/* bit 23:16, mc_reg1_32lvl */ +/* bit 15:8, mc_reg0_32lvl */ +/* bit 7:0, field_32lvl */ +#define DI_MC_32LVL1 ((0x172b)) /* << 2) + 0xd0100000) */ +/* bit 15:8, mc_reg3_32lvl */ +/* bit 7:0, mc_reg4_32lvl */ +#define DI_MC_22LVL0 ((0x172c)) /* << 2) + 0xd0100000) */ +/* bit 31:16, mc_reg0_22lvl */ +/* bit 15:0, field_22lvl */ +#define DI_MC_22LVL1 ((0x172d)) /* << 2) + 0xd0100000) */ +/* bit 31:16, mc_reg2_22lvl */ +/* bit 15:0, mc_reg1_22lvl */ +#define DI_MC_22LVL2 ((0x172e)) /* << 2) + 0xd0100000) */ +/* bit 31:16, mc_reg4_22lvl */ +/* bit 15:0, mc_reg3_22lvl */ +#define DI_MC_CTRL ((0x172f)) /* << 2) + 0xd0100000) */ +/* bit 4, mc_reg4_en */ +/* bit 3, mc_reg3_en */ +/* bit 2, mc_reg2_en */ +/* bit 1, mc_reg1_en */ +/* bit 0, mc_reg0_en */ +#define DI_INTR_CTRL ((0x1730)) /* << 2) + 0xd0100000) */ +#define DI_INFO_ADDR ((0x1731)) /* << 2) + 0xd0100000) */ +#define DI_INFO_DATA ((0x1732)) /* << 2) + 0xd0100000) */ +#define DI_PRE_HOLD ((0x1733)) /* << 2) + 0xd0100000) */ +#define DI_MTN_1_CTRL1 ((0x1740)) /* << 2) + 0xd0100000) */ +/* bit 31, mtn_1_en */ +/* bit 30, mtn_init */ +/* bit 29, di2nr_txt_en */ +/* bit 28, di2nr_txt_mode */ +/* bit 27:24, mtn_def */ +/* bit 23:16, mtn_adp_yc */ +/* bit 15:8, mtn_adp_2c */ +/* bit 7:0, mtn_adp_2y */ +#define DI_MTN_1_CTRL2 ((0x1741)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mtn_ykinter */ +/* bit 23:16, mtn_ckinter */ +/* bit 15:8, mtn_ykintra */ +/* bit 7:0, mtn_ckintra */ +#define DI_MTN_1_CTRL3 ((0x1742)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mtn_tyrate */ +/* bit 23:16, mtn_tcrate */ +/* bit 15: 8, mtn_mxcmby */ +/* bit 7: 0, mtn_mxcmbc */ +#define DI_MTN_1_CTRL4 ((0x1743)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mtn_tcorey */ +/* bit 23:16, mtn_tcorec */ +/* bit 15: 8, mtn_minth */ +/* bit 7: 0, mtn_maxth */ +#define DI_MTN_1_CTRL5 ((0x1744)) /* << 2) + 0xd0100000) */ +/* bit 31:28, mtn_m1b_extnd */ +/* bit 27:24, mtn_m1b_errod */ +/* bit 19:18, mtn_replace_cbyy */ +/* bit 17:16, mtn_replace_ybyc */ +/* bit 15: 8, mtn_core_ykinter */ +/* bit 7: 0, mtn_core_ckinter */ +#define DI_MTN_1_CTRL6 ((0x17a9)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mtn_m1b_extnd */ +/* bit 23:16, mtn_m1b_errod */ +/* bit 15: 8, mtn_core_ykinter */ +/* bit 7: 0, mtn_core_ckinter */ +#define DI_MTN_1_CTRL7 ((0x17aa)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mtn_core_mxcmby */ +/* bit 23:16, mtn_core_mxcmbc */ +/* bit 15: 8, mtn_core_y */ +/* bit 7: 0, mtn_core_c */ +#define DI_MTN_1_CTRL8 ((0x17ab)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mtn_fcore_ykinter */ +/* bit 23:16, mtn_fcore_ckinter */ +/* bit 15: 8, mtn_fcore_ykintra */ +/* bit 7: 0, mtn_fcore_ckintra */ +#define DI_MTN_1_CTRL9 ((0x17ac)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mtn_fcore_2yrate */ +/* bit 23:16, mtn_fcore_2crate */ +/* bit 15: 8, mtn_fcore_y */ +/* bit 7: 0, mtn_fcore_c */ +#define DI_MTN_1_CTRL10 ((0x17ad)) /* << 2) + 0xd0100000) */ +/* bit 27:24, mtn_motfld0 */ +/* bit 19:16, mtn_stlfld0 */ +/* bit 11: 8, mtn_motfld1 */ +/* bit 3: 0, mtn_stlfld1 */ +#define DI_MTN_1_CTRL11 ((0x17ae)) /* << 2) + 0xd0100000) */ +/* bit 27:24, mtn_smotevn */ +/* bit 20:16, mtn_smotodd */ +/* bit 11: 8, mtn_sstlevn */ +/* bit 4: 0, mtn_sstlodd */ +#define DI_MTN_1_CTRL12 ((0x17af)) /* << 2) + 0xd0100000) */ +/* bit 31:24, mtn_mgain */ +/* bit 17:16, mtn_mmode */ +/* bit 15: 8, mtn_sthrd */ +/* bit 4: 0, mtn_sgain */ +/* // DET 3D REG DEFINE BEGIN //// */ +/* // 8'h34~8'h3f */ +#define DET3D_MOTN_CFG ((0x1734)) /* << 2) + 0xd0100000) */ +/* Bit 16, reg_det3d_intr_en Det3d interrupt enable + * Bit 9:8, reg_Det3D_Motion_Mode + * U2 Different mode for Motion Calculation of Luma and Chroma: + * 0: MotY, 1: (2*MotY + (MotU + MotV))/4; + * 2: Max(MotY, MotU,MotV); 3:Max(MotY, (MotU+MotV)/2) + * Bit 7:4, reg_Det3D_Motion_Core_Rate U4 K Rate to Edge (HV) details + * for coring of Motion Calculations, normalized to 32 + * Bit 3:0, reg_Det3D_Motion_Core_Thrd + * U4 2X: static coring value for Motion Detection. + */ +#define DET3D_CB_CFG ((0x1735)) /* << 2) + 0xd0100000) */ +/* Bit 7:4, reg_Det3D_ChessBd_NHV_ofst + * U4, Noise immune offset for NON-Horizotnal or vertical combing detection. + * + * Bit 3:0, reg_Det3D_ChessBd_HV_ofst + * U4, Noise immune offset for Horizotnal or vertical combing detection. + */ +#define DET3D_SPLT_CFG ((0x1736)) /* << 2) + 0xd0100000) */ +/* Bit 7:4, reg_Det3D_SplitValid_ratio + * U4, Ratio between max_value and the avg_value of + * the edge mapping for split line valid detection. + * The smaller of this value, the easier of the split line detected. + * Bit 3:0, reg_Det3D_AvgIdx_ratio U4,Ratio to the avg_value of the + * edge mapping for split line position estimation. + */ +/* The smaller of this value, + * the more samples will be added to the estimation. + */ +#define DET3D_HV_MUTE ((0x1737)) /* << 2) + 0xd0100000) */ +/* Bit 23:20, reg_Det3D_Edge_Ver_Mute U4 X2: Horizontal pixels to be mute + * from H/V Edge calculation Top and Bottom border part. + * Bit 19:16, reg_Det3D_Edge_Hor_Mute U4 X2: Horizontal pixels to be mute + * from H/V Edge calculation Left and right border part. + * Bit 15:12, reg_Det3D_ChessBd_Ver_Mute U4 X2: Horizontal pixels to + * be mute from ChessBoard statistics calculation in middle part + * Bit 11:8, reg_Det3D_ChessBd_Hor_Mute U4 X2: Horizontal pixels to + * be mute from ChessBoard statistics calculation in middle part + * Bit 7:4, reg_Det3D_STA8X8_Ver_Mute U4 1X: Vertical pixels to be + * mute from 8x8 statistics calculation in each block. + * Bit 3:0, reg_Det3D_STA8X8_Hor_Mute U4 1X: Horizontal pixels to + * be mute from 8x8 statistics calculation in each block. + */ +#define DET3D_MAT_STA_P1M1 ((0x1738)) /* << 2) + 0xd0100000) */ +/* Bit 31:24, reg_Det3D_STA8X8_P1_K0_R8 U8 SAD to SAI ratio to decide P1, + * normalized to 256 (0.8) + * Bit 23:16, reg_Det3D_STA8X8_P1_K1_R7 U8 SAD to ENG ratio to decide P1, + * normalized to 128 (0.5) + * Bit 15:8, reg_Det3D_STA8X8_M1_K0_R6 + * U8 SAD to SAI ratio to decide M1, normalized to 64 (1.1) + * Bit 7:0, reg_Det3D_STA8X8_M1_K1_R6 + * U8 SAD to ENG ratio to decide M1, normalized to 64 (0.8) + */ +#define DET3D_MAT_STA_P1TH ((0x1739)) /* << 2) + 0xd0100000) */ +/* Bit 23:16, reg_Det3D_STAYUV_P1_TH_L4 U8 SAD to ENG Thrd offset to + * decide P1, X16 (100) + * Bit 15:8, reg_Det3D_STAEDG_P1_TH_L4 U8 SAD to ENG Thrd + * offset to decide P1, X16 (80) + * Bit 7:0, reg_Det3D_STAMOT_P1_TH_L4 U8 SAD to ENG Thrd + * offset to decide P1, X16 (48) + */ +#define DET3D_MAT_STA_M1TH ((0x173a)) /* << 2) + 0xd0100000) */ +/* Bit 23:16, reg_Det3D_STAYUV_M1_TH_L4 U8 SAD to + * ENG Thrd offset to decide M1, X16 (100) + * Bit 15:8, reg_Det3D_STAEDG_M1_TH_L4 + * U8 SAD to ENG Thrd offset to decide M1, X16 (80) + * Bit 7:0, reg_Det3D_STAMOT_M1_TH_L4 + * U8 SAD to ENG Thrd offset to decide M1, X16 (64) + */ +#define DET3D_MAT_STA_RSFT ((0x173b)) /* << 2) + 0xd0100000) */ +/* Bit 5:4, reg_Det3D_STAYUV_RSHFT U2 YUV statistics SAD and SAI + * calculation result right shift bits to accommodate the 12bits clipping: + * 0: mainly for images <=720x480: + * 1: mainly for images <=1366x768: + * 2: mainly + * for images <=1920X1080: 2; 3: other higher resolutions + * Bit 3:2, reg_Det3D_STAEDG_RSHFT U2 Horizontal and Vertical Edge + * Statistics SAD and SAI calculation result right shift bits to + * accommodate the 12bits clipping: + * 0: mainly for images <=720x480: 1: mainly for images <=1366x768: + * 2: mainly for images <=1920X1080: 2; 3: other higher resolutions + * Bit 1:0, reg_Det3D_STAMOT_RSHFT U2 Motion SAD and SAI + * calculation result right shift bits to accommodate the 12bits clipping: + * 0: mainly for images <=720x480: 1: mainly for images <=1366x768: + * 2: mainly for images <=1920X1080: 2; 3: other higher resolutions + */ +#define DET3D_MAT_SYMTC_TH ((0x173c)) /* << 2) + 0xd0100000) */ +/* Bit 31:24, reg_Det3D_STALUM_symtc_Th U8 threshold to decide + * if the Luma statistics is TB or LR symmetric. + * Bit 23:16, reg_Det3D_STACHR_symtc_Th U8 threshold to decide + * if the Chroma (UV) statistics is TB or LR symmetric. + * Bit 15:8, reg_Det3D_STAEDG_symtc_Th U8 threshold to + * decide if the Horizontal and Vertical Edge statistics is TB or LR symmetric. + * Bit 7:0, reg_Det3D_STAMOT_symtc_Th U8 threshold to + * decide if the Motion statistics is TB or LR symmetric. + */ +#define DET3D_RO_DET_CB_HOR ((0x173d)) /* << 2) + 0xd0100000) */ +/* Bit 31:16, RO_Det3D_ChessBd_NHor_value U16 X64: number of Pixels + * of Horizontally Surely NOT matching Chessboard pattern. + * Bit 15:0, RO_Det3D_ChessBd_Hor_value U16 X64: number of + * Pixels of Horizontally Surely matching Chessboard pattern. + */ +#define DET3D_RO_DET_CB_VER ((0x173e)) /* << 2) + 0xd0100000) */ +/* Bit 31:16, RO_Det3D_ChessBd_NVer_value U16 X64: number of + * Pixels of Vertically Surely NOT matching Chessboard pattern. + * Bit 15:0, RO_Det3D_ChessBd_Ver_value U16 X64: number + * of Pixels of Vertically Surely matching Chessboard pattern. + */ +#define DET3D_RO_SPLT_HT ((0x173f)) /* << 2) + 0xd0100000) */ +/* Bit 24, RO_Det3D_Split_HT_valid U1 horizontal LR split border + * detected valid signal for top half picture + * Bit 20:16, RO_Det3D_Split_HT_pxnum U5 number of pixels included for the + * LR split position estimation for top half picture + * Bit 9:0, RO_Det3D_Split_HT_idxX4 S10 X4: horizontal pixel + * shifts of LR split position to the (ColMax/2) for top half picture + * // DET 3D REG DEFINE END //// + * // NR2 REG DEFINE BEGIN//// + */ +#define NR2_MET_NM_CTRL ((0x1745)) /* << 2) + 0xd0100000) */ +/* Bit 28, reg_NM_reset Reset to the status of the Loop filter. + * Bit 27:24, reg_NM_calc_length Length mode of the Noise + * measurement sample number for statistics. + * 0: 256 samples; 1: 512 samples; 2: 1024 samples; + * ¡­X: 2^(8+x) samples + * Bit 23:20, reg_NM_inc_step Loop filter input gain increase step. + * Bit 19:16, reg_NM_dec_step Loop filter input gain decrease step. + * Bit 15:8, reg_NM_YHPmot_thrd Luma channel HP portion motion + * for condition of pixels included in Luma Noise measurement. + * Bit 7:0, reg_NM_CHPmot_thrd Chroma channel HP portion motion + * for condition of pixels included in Chroma Noise measurement. + */ +#define NR2_MET_NM_YCTRL ((0x1746)) /* << 2) + 0xd0100000) */ +/* Bit 31:28, reg_NM_YPLL_target Target rate of + * NM_Ynoise_thrd to mean of the Luma Noise + * Bit 27:24, reg_NM_YLPmot_thrd Luma channel LP + * portion motion for condition of pixels included in Luma Noise measurement. + * Bit 23:16, reg_NM_YHPmot_thrd_min Minimum threshold for + * Luma channel HP portion motion to decide whether the pixel + * will be included in Luma noise measurement. + * Bit 15:8, reg_NM_YHPmot_thrd_max Maximum threshold for Luma + * channel HP portion motion to decide whether the pixel will be included in + * Luma noise measurement. + * Bit 7:0, reg_NM_Ylock_rate Rate to decide whether the + * Luma noise measurement is lock or not. + */ +#define NR2_MET_NM_CCTRL ((0x1747)) /* << 2) + 0xd0100000) */ +/* Bit 31:28, reg_NM_CPLL_target + * Target rate of NM_Cnoise_thrd to mean of the Chroma Noise + * Bit 27:24, reg_NM_CLPmot_thrd Chroma channel LP portion motion + * for condition of pixels included in Chroma Noise measurement. + * Bit 23:16, reg_NM_CHPmot_thrd_min Minimum threshold for Chroma channel + * HP portion motion to decide whether the pixel will be + * included in Chroma noise measurement. + * Bit 15:8, reg_NM_CHPmot_thrd_max Maximum threshold for Chroma + * channel HP portion motion to decide whether the pixel will be included in + * Chroma noise measurement. + * Bit 7:0, reg_NM_Clock_rate Rate to decide whether the Chroma + * noise measurement is lock or not; + */ +#define NR2_MET_NM_TNR ((0x1748)) /* << 2) + 0xd0100000) */ +/* Bit 25, ro_NM_TNR_Ylock Read-only register to tell + * ifLuma channel noise measurement is locked or not. + * Bit 24, ro_NM_TNR_Clock Read-only register to tell + * if Chroma channel noise measurement is locked or not. + * Bit 23:12, ro_NM_TNR_Ylevel Read-only register to give Luma + * channel noise level. It was 16x of pixel difference in 8 bits of YHPmot. + * Bit 11:0, ro_NM_TNR_ClevelRead-only register to give Chroma channel noise + * level.It was 16x of pixel difference in 8 bits of CHPmot. + */ +#define NR2_MET_NMFRM_TNR_YLEV ((0x1749)) /* << 2) + 0xd0100000) */ +/* Bit 28:0, ro_NMFrm_TNR_Ylevel Frame based Read-only register + * to give Luma channel noise level within one frame/field. + */ +#define NR2_MET_NMFRM_TNR_YCNT ((0x174a)) /* << 2) + 0xd0100000) */ +/* Bit 23:0, ro_NMFrm_TNR_Ycount Number ofLuma channel pixels + * included in Frame/Field based noise level measurement. + */ +#define NR2_MET_NMFRM_TNR_CLEV ((0x174b)) /* << 2) + 0xd0100000) */ +/* Bit 28:0, ro_NMFrm_TNR_Clevel Frame based Read-only register + * to give Chroma channel noise level within one frame/field. + */ +#define NR2_MET_NMFRM_TNR_CCNT ((0x174c)) /* << 2) + 0xd0100000) */ +/* Bit 23:0, ro_NMFrm_TNR_Ccount Number of Chroma channel pixels + * included in Frame/Field based noise level measurement. + */ +#define NR2_3DEN_MODE ((0x174d)) /* << 2) + 0xd0100000) */ +/* Bit 6:4, Blend_3dnr_en_r */ +/* Bit 2:0, Blend_3dnr_en_l */ +#define NR2_IIR_CTRL ((0x174e)) /* << 2) + 0xd0100000) */ +/* Bit 15:14, reg_LP_IIR_8bit_mode LP IIR membitwidth mode: + * 0: 10bits will be store in memory; + * 1: 9bits will be store in memory; + * 2: 8bits will be store in memory; + * 3: 7bits will be store in memory; + * Bit 13:12, reg_LP_IIR_mute_mode Mode for the LP IIR mute, + * Bit 11:8,reg_LP_IIR_mute_thrd Threshold of LP IIR mute to avoid ghost: + * Bit 7:6, reg_HP_IIR_8bit_mode IIR membitwidth mode: + * 0: 10bits will be store in memory; + * 1: 9bits will be store in memory; + * 2: 8bits will be store in memory; + * 3: 7bits will be store in memory; + * Bit 5:4, reg_HP_IIR_mute_mode Mode for theLP IIR mute + * Bit 3:0,reg_HP_IIR_mute_thrd Threshold of HP IIR mute to avoid ghost + */ +#define NR2_SW_EN ((0x174f)) /* << 2) + 0xd0100000) */ +/* Bit 17:8, Clk_gate_ctrl + * Bit 7, Cfr_enable + * Bit 5, Det3d_en + * Bit 4, Nr2_proc_en + * Bit 0, Nr2_sw_en + */ +#define NR2_FRM_SIZE ((0x1750)) /* << 2) + 0xd0100000) */ +/* Bit 27:16, Frm_heigh Frame/field height */ +/* Bit 11: 0, Frm_width Frame/field width */ +#define NR2_SNR_SAD_CFG ((0x1751)) /* << 2) + 0xd0100000) */ +/* Bit 12, reg_MATNR_SNR_SAD_CenRPL U1, Enable signal for Current + * pixel position SAD to be replaced by SAD_min.0: do not replace Current pixel + * position SAD by SAD_min;1: do replacements + * Bit 11:8, reg_MATNR_SNR_SAD_coring Coring value of the intra-frame + * SAD. sum = (sum - reg_MATNR_SNR_SAD_coring); + * sum = (sum<0) ? 0: (sum>255)? 255: sum; + * Bit 6:5, reg_MATNR_SNR_SAD_WinMod Unsigned, Intra-frame SAD + * matching window mode:0: 1x1; 1: [1 1 1] 2: [1 2 1]; 3: [1 2 2 2 1]; + * Bit 4:0, Sad_coef_num Sad coeffient + */ +#define NR2_MATNR_SNR_OS ((0x1752)) /* << 2) + 0xd0100000) */ +/* Bit 7:4, reg_MATNR_SNR_COS SNR Filter overshoot control + * margin for UV channel (X2 to u10 scale) + * Bit 3:0, reg_MATNR_SNR_YOS SNR Filter overshoot control + * margin for luma channel (X2 to u10 scale) + */ +#define NR2_MATNR_SNR_NRM_CFG ((0x1753)) /* << 2) + 0xd0100000) */ +/* Bit 23:16, reg_MATNR_SNR_NRM_ofst Edge based SNR + * boosting normalization offset to SAD_max ; + * Bit 15:8, reg_MATNR_SNR_NRM_max + * Edge based SNR boosting normalization Max value + * Bit 7:0, reg_MATNR_SNR_NRM_min + * Edge based SNR boosting normalization Min value + */ +#define NR2_MATNR_SNR_NRM_GAIN ((0x1754)) /* << 2) + 0xd0100000) */ +/* Bit 15:8, reg_MATNR_SNR_NRM_Cgain Edge based SNR boosting + * normalization Gain for Chrm channel (norm 32 as 1) + * Bit 7:0, reg_MATNR_SNR_NRM_Ygain Edge based SNR boosting + * normalization Gain for Luma channel (norm 32 as 1) + */ +#define NR2_MATNR_SNR_LPF_CFG ((0x1755)) /* << 2) + 0xd0100000) */ +/* Bit 23:16,reg_MATNR_SNRLPF_SADmaxTH U8, Threshold to SADmax to use TNRLPF + * to replace SNRLPF. i.e.if (SAD_max=) between LR and LL/RR. unsigned , default = 2 + */ +/* Bit 23:16, reg_dnr_hbof_edgethd , + * edge threshold (<=) for LR . unsigned , default = 32 + */ +/* Bit 15: 8, reg_dnr_hbof_flatthd , + * flat threshold (>=) for LR . unsigned , default = 0 + */ +/* Bit 7, reserved */ +/* Bit 6: 4, reg_dnr_hbof_delta , + * delta for weighted bin accumulator. unsigned , default = 1 + */ +/* Bit 3, reserved */ +/* Bit 2: 0, reg_dnr_hbof_statmod , + * statistic mode for horizontal block offset, 0: count flags for 8-bin, + * 1: count LRs for 8-bin, 2: count difs for 8-bin, + * 3: count weighted flags for 8-bin, 4: count flags for first 32-bin, + * 5: count LRs for first 32-bin, 6 or 7: count difs for first 32-bin. + * unsigned , default = 2 + */ +#define DNR_VBOFFST_STAT ((0x2d06)) +/* Bit 31:24, reg_dnr_vbof_difthd , + * dif threshold (>=) between Up and Dw. unsigned , default = 1 + */ +/* Bit 23:16, reg_dnr_vbof_edgethd , + * edge threshold (<=) for Up/Dw. unsigned , default = 16 + */ +/* Bit 15: 8, reg_dnr_vbof_flatthd , + * flat threshold (>=) for Up/Dw. unsigned , default = 0 + */ +/* Bit 7, reserved */ +/* Bit 6: 4, reg_dnr_vbof_delta , + * delta for weighted bin accumulator. unsigned , default = 1 + */ +/* Bit 3, reserved */ +/* Bit 2: 0, reg_dnr_vbof_statmod , + * statistic mode for vertical block offset, 0: count flags for 8-bin, + * 1: count Ups for 8-bin, 2: count difs for 8-bin, 3: count weighted + * flags for 8-bin, 4: count flags for first 32-bin, 5: count Ups for + * first 32-bin, 6 or 7: count difs for first 32-bin. unsigned , default = 2 + */ +#define DNR_GBS_STAT ((0x2d07)) +/* Bit 31:24, reg_dnr_gbs_edgethd , + * edge threshold (<=) for LR . unsigned , default = 32 + */ +/* Bit 23:16, reg_dnr_gbs_flatthd , + * flat threshold (>=) for LR . unsigned , default = 0 + */ +/* Bit 15: 8, reg_dnr_gbs_varthd , + * variation threshold (<=) for Lvar/Rvar. unsigned , default = 16 + */ +/* Bit 7: 0, reg_dnr_gbs_difthd , + * dif threshold (>=) between LR and LL/RR. unsigned , default = 2 + */ +#define DNR_STAT_X_START_END ((0x2d08)) +/* Bit 31:30, reserved */ +/* Bit 29:16, reg_dnr_stat_xst . unsigned , default = 24 */ +/* Bit 15:14, reserved */ +/* Bit 13: 0, reg_dnr_stat_xed . unsigned , default = HSIZE - 25 */ +#define DNR_STAT_Y_START_END ((0x2d09)) +/* Bit 31:30, reserved */ +/* Bit 29:16, reg_dnr_stat_yst . unsigned , default = 24 */ +/* Bit 15:14, reserved */ +/* Bit 13: 0, reg_dnr_stat_yed . unsigned , default = VSIZE - 25 */ +#define DNR_LUMA ((0x2d0a)) +/* Bit 31:27, reserved */ +/* Bit 26:24, reg_dnr_luma_sqrtshft , + * left shift for fast squart of chroma, [0, 4]. unsigned , default = 2 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_dnr_luma_sqrtoffst , + * offset for fast squart of chroma. signed , default = 0 + */ +/* Bit 15, reserved */ +/* Bit 14:12, reg_dnr_luma_wcmod , + * theta related to warm/cool segment line, 0: 0, 1: 45, 2: 90, 3: 135, + * 4: 180, 5: 225, 6: 270, 7: 315. . unsigned , default = 3 + */ +/* Bit 11: 8, reg_dnr_luma_cshft , + * shift for calc. delta part, 0~8, . unsigned , default = 8 + */ +/* Bit 7: 6, reserved */ +/* Bit 5: 0, reg_dnr_luma_cgain , + * final gain for delta part, 32 normalized to "1". unsigned , default = 4 + */ +#define DNR_DB_YEDGE_THD ((0x2d0b)) +/* Bit 31:24, reg_dnr_db_yedgethd0 , + * edge threshold0 for luma . unsigned , default = 12 + */ +/* Bit 23:16, reg_dnr_db_yedgethd1 , + * edge threshold1 for luma . unsigned , default = 15 + */ +/* Bit 15: 8, reg_dnr_db_yedgethd2 , + * edge threshold2 for luma . unsigned , default = 18 + */ +/* Bit 7: 0, reg_dnr_db_yedgethd3 , + * edge threshold3 for luma . unsigned , default = 25 + */ +#define DNR_DB_CEDGE_THD ((0x2d0c)) +/* Bit 31:24, reg_dnr_db_cedgethd0 , + * edge threshold0 for chroma . unsigned , default = 12 + */ +/* Bit 23:16, reg_dnr_db_cedgethd1 , + * edge threshold1 for chroma . unsigned , default = 15 + */ +/* Bit 15: 8, reg_dnr_db_cedgethd2 , + * edge threshold2 for chroma . unsigned , default = 18 + */ +/* Bit 7: 0, reg_dnr_db_cedgethd3 , + * edge threshold3 for chroma . unsigned , default = 25 + */ +#define DNR_DB_HGAP ((0x2d0d)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_dnr_db_hgapthd , + * horizontal gap thd (<=) for very sure blockiness . unsigned , default = 8 + */ +/* Bit 15: 8, reg_dnr_db_hgapdifthd , + * dif thd between hgap and lft/rgt hdifs. unsigned , default = 1 + */ +/* Bit 7: 1, reserved */ +/* Bit 0, reg_dnr_db_hgapmod , + * horizontal gap calc. mode, 0: just use current col x, + * 1: find max between (x-1, x, x+1) . unsigned , default = 0 + */ +#define DNR_DB_HBS ((0x2d0e)) +/* Bit 31: 6, reserved */ +/* Bit 5: 4, reg_dnr_db_hbsup , + * horizontal bs up value . unsigned , default = 1 + */ +/* Bit 3: 2, reg_dnr_db_hbsmax , + * max value of hbs for global control. unsigned , default = 3 + */ +/* Bit 1: 0, reg_dnr_db_hgbsthd , + * gbs thd (>=) for hbs calc. . unsigned , default = 1 + */ +#define DNR_DB_HACT ((0x2d0f)) +/* Bit 31:16, reserved */ +/* Bit 15: 8, reg_dnr_db_hactthd0 , + * thd0 of hact, for block classification. unsigned , default = 10 + */ +/* Bit 7: 0, reg_dnr_db_hactthd1 , + * thd1 of hact, for block classification. unsigned , default = 32 + */ +#define DNR_DB_YHDELTA_GAIN ((0x2d10)) +/* Bit 31:27, reserved */ +/* Bit 26:24, reg_dnr_db_yhdeltagain1 , + * (p1-q1) gain for Y's delta calc. when bs=1, normalized 8 as "1" . + * unsigned , default = 2 + */ +/* Bit 23, reserved */ +/* Bit 22:20, reg_dnr_db_yhdeltagain2 , + * (p1-q1) gain for Y's delta calc. when bs=2, normalized 8 as "1" . + * unsigned , default = 0 + */ +/* Bit 19, reserved */ +/* Bit 18:16, reg_dnr_db_yhdeltagain3 , + * (p1-q1) gain for Y's delta calc. when bs=3, normalized 8 as "1" . + * unsigned , default = 0 + */ +/* Bit 15, reserved */ +/* Bit 14: 8, reg_dnr_db_yhdeltaadjoffst , + * offset for adjust Y's hdelta (-64, 63). signed , default = 0 + */ +/* Bit 7: 6, reserved */ +/* Bit 5: 0, reg_dnr_db_yhdeltaadjgain , + * gain for adjust Y's hdelta, normalized 32 as "1" . unsigned , default = 32 + */ +#define DNR_DB_YHDELTA2_GAIN ((0x2d11)) +/* Bit 31:30, reserved */ +/* Bit 29:24, reg_dnr_db_yhdelta2gain2 , + * gain for bs=2's adjust Y's hdelta2, normalized 64 as "1" . + * unsigned , default = 8 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_dnr_db_yhdelta2offst2 , + * offset for bs=2's adjust Y's hdelta2 (-16, 15). signed , default = 0 + */ +/* Bit 15:14, reserved */ +/* Bit 13: 8, reg_dnr_db_yhdelta2gain3 , + * gain for bs=3's adjust Y's hdelta2, normalized 64 as "1" . + * unsigned , default = 4 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_db_yhdelta2offst3 , + * offset for bs=3's adjust Y's hdelta2 (-16, 15). signed , default = 0 + */ +#define DNR_DB_CHDELTA_GAIN ((0x2d12)) +/* Bit 31:27, reserved */ +/* Bit 26:24, reg_dnr_db_chdeltagain1 , + * (p1-q1) gain for UV's delta calc. when bs=1, normalized 8 as "1". + * unsigned , default = 2 + */ +/* Bit 23, reserved */ +/* Bit 22:20, reg_dnr_db_chdeltagain2 , + * (p1-q1) gain for UV's delta calc. when bs=2, + * normalized 8 as "1". unsigned , default = 0 + */ +/* Bit 19, reserved */ +/* Bit 18:16, reg_dnr_db_chdeltagain3 , + * (p1-q1) gain for UV's delta calc. when bs=3, normalized 8 as "1". + * unsigned , default = 0 + */ +/* Bit 15, reserved */ +/* Bit 14: 8, reg_dnr_db_chdeltaadjoffst , + * offset for adjust UV's hdelta (-64, 63). signed , default = 0 + */ +/* Bit 7: 6, reserved */ +/* Bit 5: 0, reg_dnr_db_chdeltaadjgain , + * gain for adjust UV's hdelta, normalized 32 as "1". unsigned , default = 32 + */ +#define DNR_DB_CHDELTA2_GAIN ((0x2d13)) +/* Bit 31:30, reserved */ +/* Bit 29:24, reg_dnr_db_chdelta2gain2 , + * gain for bs=2's adjust UV's hdelta2, normalized 64 as "1" . + * unsigned , default = 8 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_dnr_db_chdelta2offst2 , + * offset for bs=2's adjust UV's hdelta2 (-16, 15). signed , default = 0 + */ +/* Bit 15:14, reserved */ +/* Bit 13: 8, reg_dnr_db_chdelta2gain3 , + * gain for bs=2's adjust UV's hdelta2, normalized 64 as "1" . + * unsigned , default = 4 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_db_chdelta2offst3 , + * offset for bs=2's adjust UV's hdelta2 (-16, 15). signed , default = 0 + */ +#define DNR_DB_YC_VEDGE_THD ((0x2d14)) +/* Bit 31:16, reserved */ +/* Bit 15: 8, reg_dnr_db_yvedgethd , + * special Y's edge thd for vdb. unsigned , default = 12 + */ +/* Bit 7: 0, reg_dnr_db_cvedgethd , + * special UV's edge thd for vdb. unsigned , default = 12 + */ +#define DNR_DB_VBS_MISC ((0x2d15)) +/* Bit 31:24, reg_dnr_db_vgapthd , + * vertical gap thd (<=) for very sure blockiness . unsigned , default = 8 + */ +/* Bit 23:16, reg_dnr_db_vactthd , + * thd of vact, for block classification . unsigned , default = 10 + */ +/* Bit 15: 8, reg_dnr_db_vgapdifthd , + * dif thd between vgap and vact. unsigned , default = 4 + */ +/* Bit 7: 4, reserved */ +/* Bit 3: 2, reg_dnr_db_vbsmax , + * max value of vbs for global control. unsigned , default = 2 + */ +/* Bit 1: 0, reg_dnr_db_vgbsthd , + * gbs thd (>=) for vbs calc. . unsigned , default = 1 + */ +#define DNR_DB_YVDELTA_GAIN ((0x2d16)) +/* Bit 31:30, reserved */ +/* Bit 29:24, reg_dnr_db_yvdeltaadjgain , + * gain for adjust Y's vdelta, normalized 32 as "1". unsigned , default = 32 + */ +/* Bit 23, reserved */ +/* Bit 22:16, reg_dnr_db_yvdeltaadjoffst , + * offset for adjust Y's vdelta (-64, 63). signed , default = 0 + */ +/* Bit 15:14, reserved */ +/* Bit 13: 8, reg_dnr_db_yvdelta2gain , + * gain for adjust Y's vdelta2, normalized 64 as "1". unsigned , default = 8 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_db_yvdelta2offst , + * offset for adjust Y's vdelta2 (-16, 15). signed , default = 0 + */ +#define DNR_DB_CVDELTA_GAIN ((0x2d17)) +/* Bit 31:30, reserved */ +/* Bit 29:24, reg_dnr_db_cvdeltaadjgain , + * gain for adjust UV's vdelta, normalized 32 as "1". unsigned , default = 32 + */ +/* Bit 23, reserved */ +/* Bit 22:16, reg_dnr_db_cvdeltaadjoffst , + * offset for adjust UV's vdelta (-64, 63). signed , default = 0 + */ +/* Bit 15:14, reserved */ +/* Bit 13: 8, reg_dnr_db_cvdelta2gain , + * gain for adjust UV's vdelta2, normalized 64 as "1". unsigned , default = 8 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_db_cvdelta2offst , + * offset for adjust UV's vdelta2 (-16, 15). signed , default = 0 + */ +#define DNR_RO_GBS_STAT_LR ((0x2d18)) +/* Bit 31: 0, ro_gbs_stat_lr + * . unsigned , default = 0 + */ +#define DNR_RO_GBS_STAT_LL ((0x2d19)) +/* Bit 31: 0, ro_gbs_stat_ll + * . unsigned , default = 0 + */ +#define DNR_RO_GBS_STAT_RR ((0x2d1a)) +/* Bit 31: 0, ro_gbs_stat_rr + * . unsigned , default = 0 + */ +#define DNR_RO_GBS_STAT_DIF ((0x2d1b)) +/* Bit 31: 0, ro_gbs_stat_dif + * . unsigned , default = 0 + */ +#define DNR_RO_GBS_STAT_CNT ((0x2d1c)) +/* Bit 31: 0, ro_gbs_stat_cnt + * . unsigned , default = 0 + */ +#define DNR_RO_HBOF_STAT_CNT_0 ((0x2d1d)) +/* Bit 31: 0, ro_hbof_stat_cnt0 + * . unsigned , default = 0 + */ +#define DNR_RO_HBOF_STAT_CNT_1 ((0x2d1e)) +/* Bit 31: 0, ro_hbof_stat_cnt1 + * . unsigned , default = 0 + */ +#define DNR_RO_HBOF_STAT_CNT_2 ((0x2d1f)) +/* Bit 31: 0, ro_hbof_stat_cnt2 + * . unsigned , default = 0 + */ +#define DNR_RO_HBOF_STAT_CNT_3 ((0x2d20)) +/* Bit 31: 0, ro_hbof_stat_cnt3 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_4 ((0x2d21)) +/* Bit 31: 0, ro_hbof_stat_cnt4 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_5 ((0x2d22)) +/* Bit 31: 0, ro_hbof_stat_cnt5 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_6 ((0x2d23)) +/* Bit 31: 0, ro_hbof_stat_cnt6 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_7 ((0x2d24)) +/* Bit 31: 0, ro_hbof_stat_cnt7 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_8 ((0x2d25)) +/* Bit 31: 0, ro_hbof_stat_cnt8 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_9 ((0x2d26)) +/* Bit 31: 0, ro_hbof_stat_cnt9 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_10 ((0x2d27)) +/* Bit 31: 0, ro_hbof_stat_cnt10 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_11 ((0x2d28)) +/* Bit 31: 0, ro_hbof_stat_cnt11 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_12 ((0x2d29)) +/* Bit 31: 0, ro_hbof_stat_cnt12 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_13 ((0x2d2a)) +/* Bit 31: 0, ro_hbof_stat_cnt13 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_14 ((0x2d2b)) +/* Bit 31: 0, ro_hbof_stat_cnt14 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_15 ((0x2d2c)) +/* Bit 31: 0, ro_hbof_stat_cnt15 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_16 ((0x2d2d)) +/* Bit 31: 0, ro_hbof_stat_cnt16 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_17 ((0x2d2e)) +/* Bit 31: 0, ro_hbof_stat_cnt17 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_18 ((0x2d2f)) +/* Bit 31: 0, ro_hbof_stat_cnt18 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_19 ((0x2d30)) +/* Bit 31: 0, ro_hbof_stat_cnt19 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_20 ((0x2d31)) +/* Bit 31: 0, ro_hbof_stat_cnt20 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_21 ((0x2d32)) +/* Bit 31: 0, ro_hbof_stat_cnt21 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_22 ((0x2d33)) +/* Bit 31: 0, ro_hbof_stat_cnt22 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_23 ((0x2d34)) +/* Bit 31: 0, ro_hbof_stat_cnt23 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_24 ((0x2d35)) +/* Bit 31: 0, ro_hbof_stat_cnt24 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_25 ((0x2d36)) +/* Bit 31: 0, ro_hbof_stat_cnt25 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_26 ((0x2d37)) +/* Bit 31: 0, ro_hbof_stat_cnt26 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_27 ((0x2d38)) +/* Bit 31: 0, ro_hbof_stat_cnt27 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_28 ((0x2d39)) +/* Bit 31: 0, ro_hbof_stat_cnt28 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_29 ((0x2d3a)) +/* Bit 31: 0, ro_hbof_stat_cnt29 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_30 ((0x2d3b)) +/* Bit 31: 0, ro_hbof_stat_cnt30 . unsigned , default = 0 */ +#define DNR_RO_HBOF_STAT_CNT_31 ((0x2d3c)) +/* Bit 31: 0, ro_hbof_stat_cnt31 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_0 ((0x2d3d)) +/* Bit 31: 0, ro_vbof_stat_cnt0 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_1 ((0x2d3e)) +/* Bit 31: 0, ro_vbof_stat_cnt1 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_2 ((0x2d3f)) +/* Bit 31: 0, ro_vbof_stat_cnt2 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_3 ((0x2d40)) +/* Bit 31: 0, ro_vbof_stat_cnt3 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_4 ((0x2d41)) +/* Bit 31: 0, ro_vbof_stat_cnt4 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_5 ((0x2d42)) +/* Bit 31: 0, ro_vbof_stat_cnt5 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_6 ((0x2d43)) +/* Bit 31: 0, ro_vbof_stat_cnt6 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_7 ((0x2d44)) +/* Bit 31: 0, ro_vbof_stat_cnt7 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_8 ((0x2d45)) +/* Bit 31: 0, ro_vbof_stat_cnt8 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_9 ((0x2d46)) +/* Bit 31: 0, ro_vbof_stat_cnt9 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_10 ((0x2d47)) +/* Bit 31: 0, ro_vbof_stat_cnt10 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_11 ((0x2d48)) +/* Bit 31: 0, ro_vbof_stat_cnt11 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_12 ((0x2d49)) +/* Bit 31: 0, ro_vbof_stat_cnt12 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_13 ((0x2d4a)) +/* Bit 31: 0, ro_vbof_stat_cnt13 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_14 ((0x2d4b)) +/* Bit 31: 0, ro_vbof_stat_cnt14 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_15 ((0x2d4c)) +/* Bit 31: 0, ro_vbof_stat_cnt15 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_16 ((0x2d4d)) +/* Bit 31: 0, ro_vbof_stat_cnt16 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_17 ((0x2d4e)) +/* Bit 31: 0, ro_vbof_stat_cnt17 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_18 ((0x2d4f)) +/* Bit 31: 0, ro_vbof_stat_cnt18 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_19 ((0x2d50)) +/* Bit 31: 0, ro_vbof_stat_cnt19 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_20 ((0x2d51)) +/* Bit 31: 0, ro_vbof_stat_cnt20 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_21 ((0x2d52)) +/* Bit 31: 0, ro_vbof_stat_cnt21 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_22 ((0x2d53)) +/* Bit 31: 0, ro_vbof_stat_cnt22 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_23 ((0x2d54)) +/* Bit 31: 0, ro_vbof_stat_cnt23 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_24 ((0x2d55)) +/* Bit 31: 0, ro_vbof_stat_cnt24 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_25 ((0x2d56)) +/* Bit 31: 0, ro_vbof_stat_cnt25 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_26 ((0x2d57)) +/* Bit 31: 0, ro_vbof_stat_cnt26 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_27 ((0x2d58)) +/* Bit 31: 0, ro_vbof_stat_cnt27 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_28 ((0x2d59)) +/* Bit 31: 0, ro_vbof_stat_cnt28 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_29 ((0x2d5a)) +/* Bit 31: 0, ro_vbof_stat_cnt29 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_30 ((0x2d5b)) +/* Bit 31: 0, ro_vbof_stat_cnt30 . unsigned , default = 0 */ +#define DNR_RO_VBOF_STAT_CNT_31 ((0x2d5c)) +/* Bit 31: 0, ro_vbof_stat_cnt31 . unsigned , default = 0 */ +#define DNR_DM_CTRL ((0x2d60)) +/* Bit 31:13, reserved */ +/* Bit 12, reg_dnr_dm_fedgeflg_en , + * enable edge flag calc. of each frame. unsigned , default = 1 + */ +/* Bit 11, reg_dnr_dm_fedgeflg_cl , + * clear frame edge flag if needed. unsigned , default = 1 + */ +/* Bit 10, reg_dnr_dm_fedgeflg_df , + * user defined edge when reg_dnr_dm_fedgeflg_en=0, default = 1 + */ +/* Bit 9, reg_dnr_dm_en , + * enable demosquito function . unsigned , default = 1 + */ +/* Bit 8, reg_dnr_dm_chrmen , + * enable chrome processing for demosquito. unsigned , default = 1 + */ +/* Bit 7: 6, reg_dnr_dm_level , + * demosquito level . unsigned , default = 3 + */ +/* Bit 5: 4, reg_dnr_dm_leveldw0 , + * level down when gbs is small. unsigned , default = 1 + */ +/* Bit 3: 2, reg_dnr_dm_leveldw1 , + * level down for no edge/flat blocks. unsigned , default = 1 + */ +/* Bit 1: 0, reg_dnr_dm_gbsthd , + * small/large threshold for gbs (<=). unsigned , default = 0 + */ +#define DNR_DM_NR_BLND ((0x2d61)) +/* Bit 31:25, reserved */ +/* Bit 24, reg_dnr_dm_defalpen , + * enable user define alpha for dm & nr blend. unsigned , default = 0 + */ +/* Bit 23:16, reg_dnr_dm_defalp , + * user define alpha for dm & nr blend if enable. unsigned , default = 0 + */ +/* Bit 15:14, reserved */ +/* Bit 13: 8, reg_dnr_dm_alpgain , + * gain for nr/dm alpha, normalized 32 as "1". unsigned , default = 32 + */ +/* Bit 7: 0, reg_dnr_dm_alpoffst , + * (-128, 127), offset for nr/dm alpha. signed , default = 0 + */ +#define DNR_DM_RNG_THD ((0x2d62)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_dnr_dm_rngminthd . unsigned , default = 2 */ +/* Bit 15: 8, reg_dnr_dm_rngmaxthd . unsigned , default = 64 */ +/* Bit 7: 0, reg_dnr_dm_rngdifthd . unsigned , default = 4 */ +#define DNR_DM_RNG_GAIN_OFST ((0x2d63)) +/* Bit 31:14, reserved */ +/* Bit 13: 8, reg_dnr_dm_rnggain , + * normalized 16 as "1" . unsigned , default = 16 + */ +/* Bit 7: 6, reserved */ +/* Bit 5: 0, reg_dnr_dm_rngofst . unsigned , default = 0 */ +#define DNR_DM_DIR_MISC ((0x2d64)) +/* Bit 31:30, reserved */ +/* Bit 29, reg_dnr_dm_diralpen . unsigned , default = 1 */ +/* Bit 28:24, reg_dnr_dm_diralpgain . unsigned , default = 0 */ +/* Bit 23:22, reserved */ +/* Bit 21:16, reg_dnr_dm_diralpofst . unsigned , default = 0 */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_diralpmin . unsigned , default = 0 */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_diralpmax . unsigned , default = 31 */ +#define DNR_DM_COR_DIF ((0x2d65)) +/* Bit 31: 4, reserved */ +/* Bit 3: 1, reg_dnr_dm_cordifshft . unsigned , default = 3 */ +/* Bit 0, reg_dnr_dm_cordifmod , + * 0:use max dir dif as cordif, 1: use max3x3 - min3x3 as cordif. + * unsigned , default = 1 + */ +#define DNR_DM_FLT_THD ((0x2d66)) +/* Bit 31:24, reg_dnr_dm_fltthd00 , + * block flat threshold0 for block average difference when gbs is small, + * for flat block detection. unsigned , default = 4 + */ +/* Bit 23:16, reg_dnr_dm_fltthd01 , + * block flat threshold1 for block average difference when gbs is small, + * for flat block detection. unsigned , default = 6 + */ +/* Bit 15: 8, reg_dnr_dm_fltthd10 , + * block flat threshold0 for block average difference when gbs is large, + * for flat block detection. unsigned , default = 9 + */ +/* Bit 7: 0, reg_dnr_dm_fltthd11 , + * block flat threshold1 for block average difference when gbs is large, + * for flat block detection. unsigned , default = 12 + */ +#define DNR_DM_VAR_THD ((0x2d67)) +/* Bit 31:24, reg_dnr_dm_varthd00 , + * block variance threshold0 (>=) when gbs is small, for flat block + * detection. unsigned , default = 2 + */ +/* Bit 23:16, reg_dnr_dm_varthd01 , + * block variance threshold1 (<=) when gbs is small, for flat block + * detection. unsigned , default = 15 + */ +/* Bit 15: 8, reg_dnr_dm_varthd10 , + * block variance threshold0 (>=) when gbs is large, for flat block + * detection. unsigned , default = 3 + */ +/* Bit 7: 0, reg_dnr_dm_varthd11 , + * block variance threshold1 (<=) when gbs is large, for flat block + * detection. unsigned , default = 24 + */ +#define DNR_DM_EDGE_DIF_THD ((0x2d68)) +/* Bit 31:24, reg_dnr_dm_edgethd0 , + * block edge threshold (<=) when gbs is small, for flat block detection. + * unsigned , default = 32 + */ +/* Bit 23:16, reg_dnr_dm_edgethd1 , + * block edge threshold (<=) when gbs is large, for flat block detection. + * unsigned , default = 48 + */ +/* Bit 15: 8, reg_dnr_dm_difthd0 , + * block dif threshold (<=) when gbs is small, for flat block detection. + * unsigned , default = 48 + */ +/* Bit 7: 0, reg_dnr_dm_difthd1 , + * block dif threshold (<=) when gbs is large, for flat block detection. + * unsigned , default = 64 + */ +#define DNR_DM_AVG_THD ((0x2d69)) +/* Bit 31:16, reserved */ +/* Bit 15: 8, reg_dnr_dm_avgthd0 , + * block average threshold (>=), for flat block detection. + * unsigned ,default = 160 + */ +/* Bit 7: 0, reg_dnr_dm_avgthd1 , + * block average threshold (<=), for flat block detection. unsigned + * , default = 128 + */ +#define DNR_DM_AVG_VAR_DIF_THD ((0x2d6a)) +/* Bit 31:16, reserved */ +/* Bit 15: 8, reg_dnr_dm_avgdifthd , + * block average dif threshold (<) between cur and up block, for flat + * block detection. unsigned , default = 12 + */ +/* Bit 7: 0, reg_dnr_dm_vardifthd , + * block variance dif threshold (>=) between cur and up block, for flat + * block detection. unsigned , default = 1 + */ +#define DNR_DM_VAR_EDGE_DIF_THD2 ((0x2d6b)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_dnr_dm_varthd2, block variance threshold (>=), + * for edge block detection.unsigned, default = 24 + */ +/* Bit 15: 8, reg_dnr_dm_edgethd2 , + * block edge threshold (>=), for edge block detection. unsigned , default = 40 + */ +/* Bit 7: 0, reg_dnr_dm_difthd2 , + * block dif threshold (>=), for edge block detection. unsigned , default = 80 + */ +#define DNR_DM_DIF_FLT_MISC ((0x2d6c)) +/* Bit 31:28, reg_dnr_dm_ldifoob , + * pre-defined large dif when pixel out of blocks. unsigned , default = 0 + */ +/* Bit 27:24, reg_dnr_dm_bdifoob , + * pre-defined block dif when pixel out of blocks;. unsigned , default = 0 + */ +/* Bit 23:16, reg_dnr_dm_fltalp , + * pre-defined alpha for dm and nr blending, when block is flat + * with mos.. unsigned , default = 200 + */ +/* Bit 15:12, reserved */ +/* Bit 11: 8, reg_dnr_dm_fltminbdif , + * pre-defined min block dif for dm filter, + * when block is flat with mos.. unsigned , default = 12 + */ +/* Bit 7, reserved */ +/* Bit 6: 2, reg_dnr_dm_difnormgain , + * gain for pixel dif normalization for dm filter, + * normalized 16 as "1". unsigned , default = 16 + */ +/* Bit 1, reg_dnr_dm_difnormen , + * enable pixel dif normalization for dm filter. unsigned , default = 1 + */ +/* Bit 0, reg_dnr_dm_difupden , + * enable block dif update using max of left, cur, right difs. + * unsigned , default = 0 + */ +#define DNR_DM_SDIF_LUT0_2 ((0x2d6d)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_sdiflut0 , + * normally 0-16 . unsigned , default = 16 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_sdiflut1 , + * normally 0-16 . unsigned , default = 14 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_sdiflut2 , + * normally 0-16 . unsigned , default = 13 + */ +#define DNR_DM_SDIF_LUT3_5 ((0x2d6e)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_sdiflut3 , + * normally 0-16 . unsigned , default = 10 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_sdiflut4 , + * normally 0-16 . unsigned , default = 7 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_sdiflut5 , + * normally 0-16 . unsigned , default = 5 + */ +#define DNR_DM_SDIF_LUT6_8 ((0x2d6f)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_sdiflut6 , + * normally 0-16 . unsigned , default = 3 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_sdiflut7 , + * normally 0-16 . unsigned , default = 1 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_sdiflut8 , + * normally 0-16 . unsigned , default = 0 + */ +#define DNR_DM_LDIF_LUT0_2 ((0x2d70)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_ldiflut0 , + * normally 0-16 . unsigned , default = 0 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_ldiflut1 , + * normally 0-16 . unsigned , default = 4 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_ldiflut2 , + * normally 0-16 . unsigned , default = 12 + */ +#define DNR_DM_LDIF_LUT3_5 ((0x2d71)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_ldiflut3 , + * normally 0-16 . unsigned , default = 14 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_ldiflut4 , + * normally 0-16 . unsigned , default = 15 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_ldiflut5 , + * normally 0-16 . unsigned , default = 16 + */ +#define DNR_DM_LDIF_LUT6_8 ((0x2d72)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_ldiflut6 , + * normally 0-16 . unsigned , default = 16 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_ldiflut7 , + * normally 0-16 . unsigned , default = 16 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_ldiflut8 , + * normally 0-16 . unsigned , default = 16 + */ +#define DNR_DM_DIF2NORM_LUT0_2 ((0x2d73)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_dif2normlut0 , + * normally 0-16 . unsigned , default = 16 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_dif2normlut1 , + * normally 0-16 . unsigned , default = 5 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_dif2normlut2 , + * normally 0-16 . unsigned , default = 3 + */ +#define DNR_DM_DIF2NORM_LUT3_5 ((0x2d74)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_dif2normlut3 , + * normally 0-16 . unsigned , default = 2 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_dif2normlut4 , + * normally 0-16 . unsigned , default = 2 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_dif2normlut5 , + * normally 0-16 . unsigned , default = 1 + */ +#define DNR_DM_DIF2NORM_LUT6_8 ((0x2d75)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_dnr_dm_dif2normlut6 , + * normally 0-16 . unsigned , default = 1 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_dnr_dm_dif2normlut7 , + * normally 0-16 . unsigned , default = 1 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_dnr_dm_dif2normlut8 , + * normally 0-16 . unsigned , default = 1 + */ +#define DNR_DM_GMS_THD ((0x2d76)) +/* Bit 31:16, reserved */ +/* Bit 15: 8, reg_gms_stat_thd0 . unsigned , default = 0 */ +/* Bit 7: 0, reg_gms_stat_thd1 . unsigned , default = 128 */ +#define DNR_RO_DM_GMS_STAT_CNT ((0x2d77)) +/* Bit 31: 0, ro_dm_gms_stat_cnt . unsigned , default = 0 */ +#define DNR_RO_DM_GMS_STAT_MS ((0x2d78)) +/* Bit 31: 0, ro_dm_gms_stat_ms . unsigned , default = 0 */ +/* txl added */ +#define DECOMB_DET_VERT_CON0 (0x2d80) +#define DECOMB_DET_VERT_CON1 (0x2d81) +#define DECOMB_DET_EDGE_CON0 (0x2d82) +#define DECOMB_DET_EDGE_CON1 (0x2d83) +#define DECOMB_PARA (0x2d84) +#define DECOMB_BLND_CON0 (0x2d85) +#define DECOMB_BLND_CON1 (0x2d86) +#define DECOMB_YC_THRD (0x2d87) +#define DECOMB_MTN_GAIN_OFST (0x2d88) +#define DECOMB_CMB_SEL_GAIN_OFST (0x2d89) +#define DECOMB_WIND00 (0x2d8a) +#define DECOMB_WIND01 (0x2d8b) +#define DECOMB_WIND10 (0x2d8c) +#define DECOMB_WIND11 (0x2d8d) +#define DECOMB_MODE (0x2d8e) +#define DECOMB_FRM_SIZE (0x2d8f) +#define DECOMB_HV_BLANK (0x2d90) +#define NR2_POLAR3_MODE (0x2d98) +#define NR2_POLAR3_THRD (0x2d99) +#define NR2_POLAR3_PARA0 (0x2d9a) +#define NR2_POLAR3_PARA1 (0x2d9b) +#define NR2_POLAR3_CTRL (0x2d9c) +#define NR2_RO_POLAR3_NUMOFPIX (0x2d9d) +#define NR2_RO_POLAR3_SMOOTHMV (0x2d9e) +#define NR2_RO_POLAR3_M1 (0x2d9f) +#define NR2_RO_POLAR3_P1 (0x2da0) +#define NR2_RO_POLAR3_M2 (0x2da1) +#define NR2_RO_POLAR3_P2 (0x2da2) +#define NR2_RO_POLAR3_32 (0x2da3) +/* txl end */ + + +#define VPU_VD1_MMC_CTRL (0x2703) +#define VPU_VD2_MMC_CTRL (0x2704) +#define VPU_DI_IF1_MMC_CTRL (0x2705) +#define VPU_DI_MEM_MMC_CTRL (0x2706) +#define VPU_DI_INP_MMC_CTRL (0x2707) +#define VPU_DI_MTNRD_MMC_CTRL (0x2708) +#define VPU_DI_CHAN2_MMC_CTRL (0x2709) +#define VPU_DI_MTNWR_MMC_CTRL (0x270a) +#define VPU_DI_NRWR_MMC_CTRL (0x270b) +#define VPU_DI_DIWR_MMC_CTRL (0x270c) + +#define MCDI_PD_22_CHK_WND0_X (0x2f59) +#define MCDI_PD_22_CHK_WND0_Y (0x2f5a) +#define MCDI_PD_22_CHK_WND1_X (0x2f5b) +#define MCDI_PD_22_CHK_WND1_Y (0x2f5c) +/* mc di */ +/* //=================================================================//// */ +/* // memc di core 0 */ +/* //=================================================================//// */ +#define MCDI_HV_SIZEIN ((0x2f00)) +/* Bit 31:29, reserved */ +/* Bit 28:16, reg_mcdi_hsize + * image horizontal size (number of cols) default=1024 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 0, reg_mcdi_vsize + * image vertical size (number of rows) default=1024 + */ +#define MCDI_HV_BLKSIZEIN ((0x2f01)) +/* Bit 31, reg_mcdi_vrev default = 0 */ +/* Bit 30, reg_mcdi_hrev default = 0 */ +/* Bit 29:28, reserved */ +/* Bit 27:16, reg_mcdi_blkhsize + * image horizontal blk size (number of cols) default=1024 + */ +/* Bit 15:13, reserved */ +/* Bit 11: 0, reg_mcdi_blkvsize + * image vertical blk size (number of rows) default=1024 + */ +#define MCDI_BLKTOTAL ((0x2f02)) +/* Bit 31:24, reserved */ +/* Bit 23: 0, reg_mcdi_blktotal */ +#define MCDI_MOTINEN ((0x2f03)) +/* Bit 31: 2, reserved */ +/* Bit 1, reg_mcdi_motionrefen. + * enable motion refinement of MA, default = 1 + */ +/* Bit 0, reg_mcdi_motionparadoxen. + * enable motion paradox detection, default = 1 + */ +#define MCDI_CTRL_MODE ((0x2f04)) +/* Bit 31:28, reserved */ +/* Bit 27:26, reg_mcdi_lmvlocken + * 0:disable, 1: use max Lmv, 2: use no-zero Lmv, + * lmv lock enable mode, default = 2 + */ +/* Bit 25, reg_mcdi_reldetrptchken */ +/* 0: unable; 1: enable, enable repeat pattern + * check (not repeat mv detection) in rel det part, default = 1 + */ +/* Bit 24, reg_mcdi_reldetgmvpd22chken */ +/* 0: unable; 1: enable, enable pull-down 22 mode + * check in gmv lock mode for rel det, default = 1 + */ +/* Bit 23, reg_mcdi_pd22chken */ +/* 0: unable; 1: enable, enable pull-down 22 + * mode check (lock) function, default = 1 + */ +/* Bit 22, reg_mcdi_reldetlpfen */ +/* 0: unable; 1: enable, enable det value lpf, default = 1 */ +/* Bit 21, reg_mcdi_reldetlmvpd22chken */ +/* 0: unable; 1: enable, enable pull-down 22 + * mode check in lmv lock mode for rel det, default = 1 + */ +/* Bit 20, reg_mcdi_reldetlmvdifchken */ +/* 0: unable; 1: enable, enable lmv dif check + * in lmv lock mode for rel det, default = 1 + */ +/* Bit 19, reg_mcdi_reldetgmvdifchken */ +/* 0: unable; 1: enable, enable lmv dif check in + * lmv lock mode for rel det, default = 1 + */ +/* Bit 18, reg_mcdi_reldetpd22chken */ +/* 0: unable; 1: enable, enable pull-down 22 + * mode check for rel det refinement, default = 1 + */ +/* Bit 17, reg_mcdi_reldetfrqchken */ +/* 0: unable; 1: enable, enable mv frequency check in rel det, default = 1 */ +/* Bit 16, reg_mcdi_qmeen */ +/* 0: unable; 1: enable, enable quarter motion estimation, defautl = 1 */ +/* Bit 15, reg_mcdi_refrptmven */ +/* 0: unable; 1: enable, use repeat mv in refinement, default = 1 */ +/* Bit 14, reg_mcdi_refgmven */ +/* 0: unable; 1: enable, use gmv in refinement, default = 1 */ +/* Bit 13, reg_mcdi_reflmven */ +/* 0: unable; 1: enable, use lmvs in refinement, default = 1 */ +/* Bit 12, reg_mcdi_refnmven */ +/* 0: unable; 1: enable, use neighoring mvs in refinement, default = 1 */ +/* Bit 11, reserved */ +/* Bit 10, reg_mcdi_referrfrqchken */ +/* 0: unable; 1: enable, enable mv frquency + * check while finding min err in ref, default = 1 + */ +/* Bit 9, reg_mcdi_refen */ +/* 0: unable; 1: enable, enable mv refinement, default = 1 + */ +/* Bit 8, reg_mcdi_horlineen */ +/* 0: unable; 1: enable,enable horizontal lines + * detection by sad map, default = 1 + */ +/* Bit 7, reg_mcdi_highvertfrqdeten */ +/* 0: unable; 1: enable, enable high vertical + * frequency pattern detection, default = 1 + */ +/* Bit 6, reg_mcdi_gmvlocken */ +/* 0: unable; 1: enable, enable gmv lock mode, default = 1 */ +/* Bit 5, reg_mcdi_rptmven */ +/* 0: unable; 1: enable, enable repeat pattern detection, default = 1 */ +/* Bit 4, reg_mcdi_gmven */ +/* 0: unable; 1: enable, enable global motion estimation, default = 1 */ +/* Bit 3, reg_mcdi_lmven */ +/* 0: unable; 1: enable, enable line mv estimation for hme, default = 1 */ +/* Bit 2, reg_mcdi_chkedgeen */ +/* 0: unable; 1: enable, enable check edge function, default = 1 */ +/* Bit 1, reg_mcdi_txtdeten */ +/* 0: unable; 1: enable, enable texture detection, default = 1 */ +/* Bit 0, reg_mcdi_memcen */ +/* 0: unable; 1: enable, enable of memc di, default = 1 */ +#define MCDI_UNI_MVDST ((0x2f05)) +/* Bit 31:20, reserved */ +/* Bit 19:17, reg_mcdi_unimvdstabsseg0 + * segment0 for uni-mv abs, default = 1 + */ +/* Bit 16:12, reg_mcdi_unimvdstabsseg1 + * segment1 for uni-mv abs, default = 15 + */ +/* Bit 11: 8, reg_mcdi_unimvdstabsdifgain0 + * 2/2, gain0 of uni-mv abs dif for segment0, normalized 2 to '1', default = 2 + */ +/* Bit 7: 5, reg_mcdi_unimvdstabsdifgain1 + * 2/2, gain1 of uni-mv abs dif for segment1, normalized 2 to '1', default = 2 + */ +/* Bit 4: 2, reg_mcdi_unimvdstabsdifgain2 + * 2/2, gain2 of uni-mv abs dif beyond segment1,normalized 2 to '1', default = 2 + */ +/* Bit 1: 0, reg_mcdi_unimvdstsgnshft + * shift for neighboring distance of uni-mv, default = 0 + */ +#define MCDI_BI_MVDST ((0x2f06)) +/* Bit 31:20, reserved */ +/* Bit 19:17, reg_mcdi_bimvdstabsseg0 + * segment0 for bi-mv abs, default = 1 + */ +/* Bit 16:12, reg_mcdi_bimvdstabsseg1 + * segment1 for bi-mv abs, default = 9 + */ +/* Bit 11: 8, reg_mcdi_bimvdstabsdifgain0 + * 6/2, gain0 of bi-mv abs dif for segment0, normalized 2 to '1', default = 6 + */ +/* Bit 7: 5, reg_mcdi_bimvdstabsdifgain1 + * 3/2, gain1 of bi-mvabs dif for segment1, normalized 2 to '1', default = 3 + */ +/* Bit 4: 2, reg_mcdi_bimvdstabsdifgain2 + * 2/2, gain2 of bi-mvabs dif beyond segment1, normalized 2 to '1', default = 2 + */ +/* Bit 1: 0, reg_mcdi_bimvdstsgnshft + * shift for neighboring distance of bi-mv, default = 0 + */ +#define MCDI_SAD_GAIN ((0x2f07)) +/* Bit 31:19, reserved */ +/* Bit 18:17, reg_mcdi_unisadcorepxlgain + * uni-sad core pixels gain, default = 3 + */ +/* Bit 16, reg_mcdi_unisadcorepxlnormen + * enable uni-sad core pixels normalization, default = 0 + */ +/* Bit 15:11, reserved */ +/* Bit 10: 9, reg_mcdi_bisadcorepxlgain + * bi-sad core pixels gain, default = 3 + */ +/* Bit 8, reg_mcdi_bisadcorepxlnormen + * enable bi-sad core pixels normalization, default = 1 + */ +/* Bit 7: 3, reserved */ +/* Bit 2: 1, reg_mcdi_biqsadcorepxlgain + * bi-qsad core pixels gain, default = 3 + */ +/* Bit 0, reg_mcdi_biqsadcorepxlnormen + * enable bi-qsad core pixels normalization, default = 1 + */ +#define MCDI_TXT_THD ((0x2f08)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_mcdi_txtminmaxdifthd, + * min max dif threshold (>=) for texture detection, default = 24 + */ +/* Bit 15: 8, reg_mcdi_txtmeandifthd, + * mean dif threshold (<) for texture detection, default = 9 + */ +/* Bit 7: 3, reserved */ +/* Bit 2: 0, reg_mcdi_txtdetthd, + * texture detecting threshold, 0~4, default = 2 + */ +#define MCDI_FLT_MODESEL ((0x2f09)) +/* Bit 31 reserved */ +/* Bit 30:28, reg_mcdi_flthorlineselmode + * mode for horizontal line detecting flat calculation,default = 1,same as below + */ +/* Bit 27 reserved */ +/* Bit 26:24, reg_mcdi_fltgmvselmode + * mode for gmv flat calculation, default = 4, same as below + */ +/* Bit 23, reserved */ +/* Bit 22:20, reg_mcdi_fltsadselmode + * mode for sad flat calculation, default = 2, same as below + */ +/* Bit 19, reserved */ +/* Bit 18:16, reg_mcdi_fltbadwselmode + * mode for badw flat calculation, default = 3, same as below + */ +/* Bit 15, reserved */ +/* Bit 14:12, reg_mcdi_fltrptmvselmode + * mode for repeat mv flat calculation, default = 4, same as below + */ +/* Bit 11, reserved */ +/* Bit 10: 8, reg_mcdi_fltbadrelselmode + * mode for bad rel flat calculation, default = 4, same as below + */ +/* Bit 7, reserved */ +/* Bit 6: 4, reg_mcdi_fltcolcfdselmode + * mode for col cfd flat calculation, default = 2, same as below + */ +/* Bit 3, reserved */ +/* Bit 2: 0, reg_mcdi_fltpd22chkselmode + * mode for pd22 check flat calculation, default = 2, # + * 0:cur dif h, 1: cur dif v, 2: pre dif h, 3: pre dif v, + * 4: cur flt, 5: pre flt, 6: cur+pre, 7: max all(cur,pre) + */ +#define MCDI_CHK_EDGE_THD ((0x2f0a)) +/* Bit 23:28, reserved. */ +/* Bit 27:24, reg_mcdi_chkedgedifsadthd. + * thd (<=) for sad dif check, 0~8, default = 1 + */ +/* Bit 23:16, reserved. */ +/* Bit 15:12, reg_mcdi_chkedgemaxedgethd. + * max drt of edge, default = 15 + */ +/* Bit 11: 8, reg_mcdi_chkedgeminedgethd. + * min drt of edge, default = 2 + */ +/* Bit 7, reserved. */ +/* Bit 6: 0, reg_mcdi_chkedgevdifthd. + * thd for vertical dif in check edge, default = 14 + */ +#define MCDI_CHK_EDGE_GAIN_OFFST ((0x2f0b)) +/* Bit 31:24, reserved. */ +/* Bit 23:20, reg_mcdi_chkedgedifthd1. + * thd1 for edge dif check (<=), default = 4 + */ +/* Bit 19:16, reg_mcdi_chkedgedifthd0. + * thd0 for edge dif check (>=), default = 15 + */ +/* Bit :15, reserved. */ +/* Bit 14:10, reg_mcdi_chkedgechklen. + * total check length for edge check, 1~24 (>0), default = 24 + */ +/* Bit 9: 8, reg_mcdi_chkedgeedgesel. + * final edge select mode, 0: original start edge, 1: lpf start edge, + * 2: orignal start+end edge, 3: lpf start+end edge, default = 1 + */ +/* Bit 7: 3, reg_mcdi_chkedgesaddstgain. + * distance gain for sad calc while getting edges, default = 4 + */ +/* Bit 2, reg_mcdi_chkedgechkmode. + * edge used in check mode, 0: original edge, 1: lpf edge, defautl = 1 + */ +/* Bit 1, reg_mcdi_chkedgestartedge. + * edge mode for start edge, 0: original edge, 1: lpf edge, defautl = 0 + */ +/* Bit 0, reg_mcdi_chkedgeedgelpf. + * edge lpf mode, 0:[0,2,4,2,0], 1:[1,2,2,2,1], default = 0 + */ +#define MCDI_LMV_RT ((0x2f0c)) +/* BIt 31:15, reserved */ +/* Bit 14:12, reg_mcdi_lmvvalidmode + * valid mode for lmv calc., 100b:use char det, 010b: use flt,001b: use hori flg + */ +/* Bit 11:10, reg_mcdi_lmvgainmvmode + * four modes of mv selection for lmv weight calucluation, default = 1 + */ +/* 0: cur(x-3), lst(x-1,x,x+1); 1: cur(x-4,x-3), lst(x,x+1); + * 2: cur(x-5,x-4,x-3), lst(x-1,x,x+1,x+2,x+3); + * 3: cur(x-6,x-5,x-4,x-3), lst(x-1,x,x+1,x+2); + */ +/* Bit 9, reg_mcdi_lmvinitmode + * initial lmvs at first row of input field, 0: initial value = 0; + * 1: initial = 32 (invalid), default = 0 + */ +/* Bit 8, reserved */ +/* Bit 7: 4, reg_mcdi_lmvrt0 ratio of max mv, default = 5 */ +/* Bit 3: 0, reg_mcdi_lmvrt1 ratio of second max mv, default = 5 */ +#define MCDI_LMV_GAINTHD ((0x2f0d)) +/* Bit 31:24, reg_mcdi_lmvvxmaxgain max gain of lmv weight, default = 96 */ +/* Bit 23, reserved */ +/* Bit 22:20, reg_mcdi_lmvdifthd0 + * dif threshold 0 (<) for small lmv, default = 1 + */ +/* Bit 19:17, reg_mcdi_lmvdifthd1 + * dif threshold 1 (<) for median lmv, default = 2 + */ +/* Bit 16:14, reg_mcdi_lmvdifthd2 + * dif threshold 2 (<) for large lmv, default = 3 + */ +/* Bit 13: 8, reg_mcdi_lmvnumlmt + * least/limit number of (total number - max0), default = 20 + */ +/* Bit 7: 0, reg_mcdi_lmvfltthd + * flt cnt thd (<) for lmv, default = 9 + */ +#define MCDI_RPTMV_THD0 ((0x2f0e)) +/* Bit 31:25, reg_mcdi_rptmvslpthd2 + * slope thd (>=) between i and i+3/i-3 (i+4/i-4), default = 64 + */ +/* Bit 24:20, reg_mcdi_rptmvslpthd1 + * slope thd (>=) between i and i+2/i-2, default = 4 + */ +/* Bit 19:10, reg_mcdi_rptmvampthd2 + * amplitude thd (>=) between max and min, when count cycles, default = 300 + */ +/* Bit 9: 0, reg_mcdi_rptmvampthd1 + * amplitude thd (>=) between average of max and min, default = 400 + */ +#define MCDI_RPTMV_THD1 ((0x2f0f)) +/* Bit 31:28, reserved */ +/* Bit 27:25, reg_mcdi_rptmvcyccntthd + * thd (>=) of total cycles count, default = 2 + */ +/* Bit 24:21, reg_mcdi_rptmvcycdifthd + * dif thd (<) of cycles length, default = 3 + */ +/* Bit 20:18, reg_mcdi_rptmvcycvldthd + * thd (>) of valid cycles number, default = 1 + */ +/* Bit 17:15, reg_mcdi_rptmvhalfcycminthd + * min length thd (>=) of half cycle, default = 2 + */ +/* Bit 14:11, reg_mcdi_rptmvhalfcycdifthd + * neighboring half cycle length dif thd (<), default = 5 + */ +/* Bit 10: 8, reg_mcdi_rptmvminmaxcntthd + * least number of valid max and min, default = 2 + */ +/* Bit 7: 5, reg_mcdi_rptmvcycminthd + * min length thd (>=) of cycles, default = 2 + */ +/* Bit 4: 0, reg_mcdi_rptmvcycmaxthd + * max length thd (<) of cycles, default = 17 + */ +#define MCDI_RPTMV_THD2 ((0x2f10)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_mcdi_rptmvhdifthd0 + * higher hdif thd (>=) (vertical edge) for rpt detection, default = 8 + */ +/* Bit 15: 8, reg_mcdi_rptmvhdifthd1 + * hdif thd (>=) (slope edge) for rpt detection, default = 4 + */ +/* Bit 7: 0, reg_mcdi_rptmvvdifthd + * vdif thd (>=) (slope edge) for rpt detection, default = 1 + */ +#define MCDI_RPTMV_SAD ((0x2f11)) +/* Bit 31:26, reserved */ +/* Bit 25:16, reg_mcdi_rptmvsaddifthdgain + * 7x3x(16/16), gain for sad dif thd in rpt mv detection, + * 0~672, normalized 16 as '1', default = 336 + */ +/* Bit 15:10, reserved */ +/* Bit 9: 0, reg_mcdi_rptmvsaddifthdoffst + * offset for sad dif thd in rpt mv detection, -512~511, default = 16 + */ +#define MCDI_RPTMV_FLG ((0x2f12)) +/* Bit 31:18, reserved */ +/* Bit 17:16, reg_mcdi_rptmvmode + * select mode of mvs for repeat motion estimation, 0: hmv, + * 1: qmv/2, 2 or 3: qmv/4, default = 2 + */ +/* Bit 15: 8, reg_mcdi_rptmvflgcntthd + * thd (>=) of min count number for rptmv of whole field, + * for rptmv estimation, default = 64 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_rptmvflgcntrt + * 4/32, ratio for repeat mv flag count, normalized 32 as '1', set 31 to 32, + */ +#define MCDI_RPTMV_GAIN ((0x2f13)) +/* Bit 31:24, reg_mcdi_rptmvlftgain + * up repeat mv gain for hme, default = 96 + */ +/* Bit 23:16, reg_mcdi_rptmvuplftgain + * up left repeat mv gain for hme, default = 32 + */ +/* Bit 15: 8, reg_mcdi_rptmvupgain + * up repeat mv gain for hme, default = 64 + */ +/* Bit 7: 0, reg_mcdi_rptmvuprightgain + * up right repeat mv gain for hme, default = 32 + */ +#define MCDI_GMV_RT ((0x2f14)) +/* Bit 31, reserved */ +/* Bit 30:24, reg_mcdi_gmvmtnrt0 + * ratio 0 for motion senario, set 127 to 128, normalized 128 as '1',default =32 + */ +/* Bit 23, reserved */ +/* Bit 22:16, reg_mcdi_gmvmtnrt1 + * ratio 1 for motion senario, set 127 to 128 normalized 128 as '1',default = 56 + */ +/* Bit 15, reserved */ +/* Bit 14: 8, reg_mcdi_gmvstlrt0 + * ratio 0 for still senario, set 127 to 128,normalized 128 as '1', default = 56 + */ +/* Bit 7, reserved */ +/* Bit 6: 0, reg_mcdi_gmvstlrt1 + * ratio 1 for still senario, set 127 to 128, normalized 128 as '1',default = 80 + */ +#define MCDI_GMV_GAIN ((0x2f15)) +/* Bit 31:25, reg_mcdi_gmvzeromvlockrt0 + * ratio 0 for locking zero mv, set 127 to 128, + * normalized 128 as '1', default = 100 + */ +/* Bit 24:18, reg_mcdi_gmvzeromvlockrt1 + * ratio 1 for locking zero mv, set 127 to 128, + * normalized 128 as '1', default = 112 + */ +/* Bit 17:16, reg_mcdi_gmvvalidmode + * valid mode for gmv calc., 10b: use flt, 01b: use hori flg, default = 3 + */ +/* Bit 15: 8, reg_mcdi_gmvvxgain + * gmv's vx gain when gmv locked for hme, default = 0 + */ +/* Bit 7: 0, reg_mcdi_gmvfltthd + * flat thd (<) for gmv calc. default = 3 + */ +#define MCDI_HOR_SADOFST ((0x2f16)) +/* Bit 31:25, reserved */ +/* Bit 24:16, reg_mcdi_horsaddifthdgain + * 21*1/8, gain/divisor for sad dif threshold in hor line detection, + * normalized 8 as '1', default = 21 + */ +/* Bit 15: 8, reg_mcdi_horsaddifthdoffst + * offset for sad dif threshold in hor line detection, -128~127, default = 0 + */ +/* Bit 7: 0, reg_mcdi_horvdifthd + * threshold (>=) of vertical dif of next block for + * horizontal line detection, default = 24 + */ +#define MCDI_REF_MV_NUM ((0x2f17)) +/* Bit 31: 2, reserved */ +/* Bit 1: 0, reg_mcdi_refmcmode. motion compensated mode used in + * refinement, 0: pre, 1: next, 2: (pre+next)/2, default = 0 + */ +#define MCDI_REF_BADW_THD_GAIN ((0x2f18)) +/* Bit 31:28, reserved */ +/* Bit 27:24, reg_mcdi_refbadwcnt2gain. + * gain for badwv count num==3, default = 6 + */ +/* Bit 23:20, reg_mcdi_refbadwcnt1gain. + * gain for badwv count num==2, default = 3 + */ +/* Bit 19:16, reg_mcdi_refbadwcnt0gain. + * gain for badwv count num==1, default = 1 + */ +/* Bit 15:12, reg_mcdi_refbadwthd3. + * threshold 3 for detect badweave with largest average luma, default = 4 + */ +/* Bit 11: 8, reg_mcdi_refbadwthd2. + * threshold 2 for detect badweave with third smallest average luma, default = 3 + */ +/* Bit 7: 4, reg_mcdi_refbadwthd1. + * threshold 1 for detect badweave with second smallest average luma,default = 2 + */ +/* Bit 3: 0, reg_mcdi_refbadwthd0. + * threshold 0 for detect badweave with smallest average luma, default = 1 + */ +#define MCDI_REF_BADW_SUM_GAIN ((0x2f19)) +/* Bit 31:13, reserved */ +/* Bit 12: 8, reg_mcdi_refbadwsumgain0. + * sum gain for r channel, 0~16, default = 8 + */ +/* Bit 7: 5, reserved */ +/* Bit 4, reg_mcdi_refbadwcalcmode. + * mode for badw calculation, 0:sum, 1:max, default = 0 + */ +/* Bit 3: 0, reserved */ +#define MCDI_REF_BS_THD_GAIN ((0x2f1a)) +/* Bit 31:28, reg_mcdi_refbsudgain1. + * up & down block stregth gain1, normalized to 8 as '1', default = 2 + */ +/* Bit 27:24, reg_mcdi_refbsudgain0. + * up & down block stregth gain0, normalized to 8 as '1', default = 4 + */ +/* Bit 23:19, reserved */ +/* Bit 18:16, reg_mcdi_refbslftgain. + * left block strength gain, default = 0 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_refbsthd1. + * threshold 1 for detect block stregth in refinment, default = 16 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_refbsthd0. + * threshold 0 for detect block stregth in refinment, default = 8 + */ +#define MCDI_REF_ERR_GAIN0 ((0x2f1b)) +/* Bit 31, reserved */ +/* Bit 30:24, reg_mcdi_referrnbrdstgain. + * neighoring mv distances gain for err calc. in ref, + * normalized to 8 as '1', default = 48 + */ +/* Bit 23:20, reserved */ +/* Bit 19:16, reg_mcdi_referrbsgain. + * bs gain for err calc. in ref, normalized to 8 as '1', default = 4 + */ +/* Bit 15, reserved */ +/* Bit 14: 8, reg_mcdi_referrbadwgain. + * badw gain for err calc. in ref, normalized to 8 as '1', default = 64 + */ +/* Bit 7: 4, reserved */ +/* Bit 3: 0, reg_mcdi_referrsadgain. + * sad gain for err calc. in ref, normalized to 8 as '1', default = 4 + */ +#define MCDI_REF_ERR_GAIN1 ((0x2f1c)) +/* Bit 31:20, reserved */ +/* Bit 19:16, reg_mcdi_referrchkedgegain. + * check edge gain for err calc. in ref, normalized to 8 as '1', default = 4 + */ +/* Bit 15:12, reserved */ +/* Bit 11: 8, reg_mcdi_referrlmvgain. + * (locked) lmv gain for err calc. in ref, normalized to 8 as '1', default = 0 + */ +/* Bit 7: 4, reserved */ +/* Bit 3: 0, reg_mcdi_referrgmvgain. + * (locked) gmv gain for err calc. in ref, normalized to 8 as '1', default = 0 + */ +#define MCDI_REF_ERR_FRQ_CHK ((0x2f1d)) +/* Bit 31:28, reserved */ +/* Bit 27:24, reg_mcdi_referrfrqgain. + * gain for mv frquency, normalized to 4 as '1', default = 10 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_mcdi_referrfrqmax. + * max gain for mv frquency check, default = 31 + */ +/* Bit 15, reserved */ +/* Bit 14:12, reg_mcdi_ref_errfrqmvdifthd2. + * mv dif threshold 2 (<) for mv frquency check, default = 3 + */ +/* Bit 11, reserved */ +/* Bit 10: 8, reg_mcdi_ref_errfrqmvdifthd1. + * mv dif threshold 1 (<) for mv frquency check, default = 2 + */ +/* Bit 7, reserved */ +/* Bit 6: 4, reg_mcdi_ref_errfrqmvdifthd0. + * mv dif threshold 0 (<) for mv frquency check, default = 1 + */ +/* Bit 3: 0, reserved */ +#define MCDI_QME_LPF_MSK ((0x2f1e)) +/* Bit 31:28, reserved */ +/* Bit 27:24, reg_mcdi_qmechkedgelpfmsk0. + * lpf mask0 for chk edge in qme, 0~8, msk1 = (8-msk0), + * normalized to 8 as '1', default = 7 + */ +/* Bit 23:20, reserved */ +/* Bit 19:16, reg_mcdi_qmebslpfmsk0. + * lpf mask0 for bs in qme, 0~8, msk1 = (8-msk0), + * normalized to 8 as '1', default = 7 + */ +/* Bit 15:12, reserved */ +/* Bit 11: 8, reg_mcdi_qmebadwlpfmsk0. + * lpf mask0 for badw in qme, 0~8, msk1 = (8-msk0), + * normalized to 8 as '1', default = 7 + */ +/* Bit 7: 4, reserved */ +/* Bit 3: 0, reg_mcdi_qmesadlpfmsk0. + * lpf mask0 for sad in qme, 0~8, msk1 = (8-msk0), + * normalized to 8 as '1', default = 7 + */ +#define MCDI_REL_DIF_THD_02 ((0x2f1f)) +/* Bit 31:24, reserved. */ +/* Bit 23:16, reg_mcdi_reldifthd2. + * thd (<) for (hdif+vdif), default = 9 + */ +/* Bit 15: 8, reg_mcdi_reldifthd1. + * thd (<) for (vdif), default = 5 + */ +/* Bit 7: 0, reg_mcdi_reldifthd0. + * thd (>=) for (hdif-vdif), default = 48 + */ +#define MCDI_REL_DIF_THD_34 ((0x2f20)) +/* Bit 31:16, reserved. */ +/* Bit 15: 8, reg_mcdi_reldifthd4. + * thd (<) for (hdif), default = 255 + */ +/* Bit 7: 0, reg_mcdi_reldifthd3. + * thd (>=) for (vdif-hdif), default = 48 + */ +#define MCDI_REL_BADW_GAIN_OFFST_01 ((0x2f21)) +/* Bit 31:24, reg_mcdi_relbadwoffst1. + * offset for badw adj, for flat block, -128~127, default = 0 + */ +/* Bit 23:16, reg_mcdi_relbadwgain1. + * gain for badw adj, for flat block, default = 128 + */ +/* Bit 15: 8, reg_mcdi_relbadwoffst0. + * offset for badw adj, for vertical block, -128~127, default = 0 + */ +/* Bit 7: 0, reg_mcdi_relbadwgain0. + * gain for badw adj, for vertical block, default = 160 + */ +#define MCDI_REL_BADW_GAIN_OFFST_23 ((0x2f22)) +/* Bit 31:24, reg_mcdi_relbadwoffst3. + * offset for badw adj, for other block, -128~127, default = 0 + */ +/* Bit 23:16, reg_mcdi_relbadwgain3. + * gain for badw adj, for other block, default = 48 + */ +/* Bit 15: 8, reg_mcdi_relbadwoffst2. + * offset for badw adj, for horizontal block, -128~127, default = 0 + */ +/* Bit 7: 0, reg_mcdi_relbadwgain2. + * gain for badw adj, for horizontal block, default = 48 + */ +#define MCDI_REL_BADW_THD_GAIN_OFFST ((0x2f23)) +/* Bit 31:23, reserved. */ +/* Bit 22:16, reg_mcdi_relbadwoffst. + * offset for badw thd adj, -64~63, default = 0 + */ +/* Bit 15: 8, reserved. */ +/* Bit 7: 0, reg_mcdi_relbadwthdgain. + * gain0 for badw thd adj, normalized to 16 as '1', default = 16 + */ +#define MCDI_REL_BADW_THD_MIN_MAX ((0x2f24)) +/* Bit 31:18, reserved. */ +/* Bit 17: 8, reg_mcdi_relbadwthdmax. + * max for badw thd adj, default = 256 + */ +/* Bit 7: 0, reg_mcdi_relbadwthdmin. + * min for badw thd adj, default = 16 + */ +#define MCDI_REL_SAD_GAIN_OFFST_01 ((0x2f25)) +/* Bit 31:24, reg_mcdi_relsadoffst1. + * offset for sad adj, for flat block, -128~127, default = 0 + */ +/* Bit 23:20, reserved. */ +/* Bit 19:16, reg_mcdi_relsadgain1. + * gain for sad adj, for flat block, normalized to 8 as '1', default = 8 + */ +/* Bit 15: 8, reg_mcdi_relsadoffst0. + * offset for sad adj, for vertical block, -128~127, default = 0 + */ +/* Bit 7: 4, reserved. */ +/* Bit 3: 0, reg_mcdi_relsadgain0. + * gain for sad adj, for vertical block, normalized to 8 as '1', default = 6 + */ +#define MCDI_REL_SAD_GAIN_OFFST_23 ((0x2f26)) +/* Bit 31:24, reg_mcdi_relsadoffst3. + * offset for sad adj, for other block, -128~127, default = 0 + */ +/* Bit 23:20, reserved. */ +/* Bit 19:16, reg_mcdi_relsadgain3. + * gain for sad adj, for other block, normalized to 8 as '1', default = 8 + */ +/* Bit 15: 8, reg_mcdi_relsadoffst2. + * offset for sad adj, for horizontal block, -128~127, default = 0 + */ +/* Bit 7: 4, reserved. */ +/* Bit 3: 0, reg_mcdi_relsadgain2. + * gain for sad adj, for horizontal block, normalized to 8 as '1', default = 12 + */ +#define MCDI_REL_SAD_THD_GAIN_OFFST ((0x2f27)) +/* Bit 31:24, reserved. */ +/* Bit 23:16, reg_mcdi_relsadoffst. + * offset for sad thd adj, -128~127, default = 0 + */ +/* Bit 15:10, reserved. */ +/* Bit 9: 0, reg_mcdi_relsadthdgain. + * gain for sad thd adj, 21*2/16, normalized to 16 as '1', default = 42 + */ +#define MCDI_REL_SAD_THD_MIN_MAX ((0x2f28)) +/* Bit 31:27, reserved. */ +/* Bit 26:16, reg_mcdi_relsadthdmax. + * max for sad thd adj, 21*32, default = 672 + */ +/* Bit 15: 9, reserved. */ +/* Bit 8: 0, reg_mcdi_relsadthdmin. + * min for sad thd adj, 21*2, default = 42 + */ +#define MCDI_REL_DET_GAIN_00 ((0x2f29)) +/* Bit 31:21, reserved. */ +/* Bit 20:16, reg_mcdi_reldetbsgain0. + * gain0 (gmv locked) for bs, for det. calc. normalized to 16 as '1', + * default = 8 + */ +/* Bit 15:14, reserved. */ +/* Bit 13: 8, reg_mcdi_reldetbadwgain0. + * gain0 (gmv locked) for badw, for det. calc. + * normalized to 16 as '1', default = 12 + */ +/* Bit 7: 5, reserved. */ +/* Bit 4: 0, reg_mcdi_reldetsadgain0. + * gain0 (gmv locked) for qsad, for det. calc. + * normalized to 16 as '1', default = 8 + */ +#define MCDI_REL_DET_GAIN_01 ((0x2f2a)) +/* Bit 31:14, reserved. */ +/* Bit 12: 8, reg_mcdi_reldetchkedgegain0. + * gain0 (gmv locked) for chk_edge, for det. calc. + * normalized to 16 as '1', default = 2 + */ +/* Bit 7, reserved. */ +/* Bit 6: 0, reg_mcdi_reldetnbrdstgain0. + * gain0 (gmv locked) for neighoring dist, for det. + * calc. normalized to 16 as '1', default = 24 + */ +#define MCDI_REL_DET_GAIN_10 ((0x2f2b)) +/* Bit 31:21, reserved. */ +/* Bit 20:16, reg_mcdi_reldetbsgain1. + * gain1 (lmv locked) for bs, for det. calc. normalized + * to 16 as '1', default = 0 + */ +/* Bit 15:14, reserved. */ +/* Bit 13: 8, reg_mcdi_reldetbadwgain1. + * gain1 (lmv locked) for badw, for det. calc. + * normalized to 16 as '1', default = 8 + */ +/* Bit 7: 5, reserved. */ +/* Bit 4: 0, reg_mcdi_reldetsadgain1. + * gain1 (lmv locked) for qsad, for det. calc. + * normalized to 16 as '1', default = 8 + */ +#define MCDI_REL_DET_GAIN_11 ((0x2f2c)) +/* Bit 31:14, reserved. */ +/* Bit 12: 8, reg_mcdi_reldetchkedgegain1. + * gain1 (lmv locked) for chk_edge, for det. calc. + * normalized to 16 as '1', default = 0 + */ +/* Bit 7, reserved. */ +/* Bit 6: 0, reg_mcdi_reldetnbrdstgain1. + * gain1 (lmv locked) for neighoring dist, for det. + * calc. normalized to 16 as '1', default = 24 + */ +#define MCDI_REL_DET_GAIN_20 ((0x2f2d)) +/* Bit 31:21, reserved. */ +/* Bit 20:16, reg_mcdi_reldetbsgain2. + * gain2 (no locked) for bs, for det. calc.normalized to 16 as '1', default = 12 + */ +/* Bit 15:14, reserved. */ +/* Bit 13: 8, reg_mcdi_reldetbadwgain2. + * gain2 (no locked) for badw, for det. calc. + * normalized to 16 as '1',default = 32 + */ +/* Bit 7: 5, reserved. */ +/* Bit 4: 0, reg_mcdi_reldetsadgain2. + * gain2 (no locked) for qsad, for det. calc. + * normalized to 16 as '1', default = 16 + */ +#define MCDI_REL_DET_GAIN_21 ((0x2f2e)) +/* Bit 31:26, reserved */ +/* Bit 25:16, reg_mcdi_reldetoffst. + * offset for rel calculation, for det. calc. -512~511, default = 0 + */ +/* Bit 15:14, reserved. */ +/* Bit 12: 8, reg_mcdi_reldetchkedgegain2. + * gain2 (no locked) for chk_edge, for det. calc. + * normalized to 16 as '1', default = 10 + */ +/* Bit 7, reserved. */ +/* Bit 6: 0, reg_mcdi_reldetnbrdstgain2. + * gain2 (no locked) for neighoring dist, for det. calc. + * normalized to 16 as '1', default = 32 + */ +#define MCDI_REL_DET_GMV_DIF_CHK ((0x2f2f)) +/* Bit 31:24, reserved. */ +/* Bit 23:16, reg_mcdi_reldetgmvfltthd. + * flat thd (>=) for gmv lock decision, default = 0 + */ +/* Bit 15, reserved. */ +/* Bit 14:12, reg_mcdi_reldetgmvdifthd. + * dif thd (>=) for current mv different from gmv for gmv dif check, + * actually used in Lmv lock check, default = 3 + */ +/* Bit 11, reserved. */ +/* Bit 10: 8, reg_mcdi_reldetgmvdifmin. + * min mv dif for gmv dif check, default = 1, note: dif between + * reg_mcdi_rel_det_gmv_dif_max and reg_mcdi_rel_det_gmv_dif_min + * should be; 0,1,3,7, not work for others + */ +/* Bit 7: 4, reg_mcdi_reldetgmvdifmax. + * max mv dif for gmv dif check, default = 4 + */ +/* Bit 3: 1, reserved */ +/* Bit 0, reg_mcdi_reldetgmvdifmvmode. + * mv mode used for gmv dif check, 0: use refmv, 1: use qmv, default = 0 + */ +#define MCDI_REL_DET_LMV_DIF_CHK ((0x2f30)) +/* Bit 31:24, reserved. */ +/* Bit 23:16, reg_mcdi_reldetlmvfltthd. + * flat thd (>=) for lmv lock decision, default = 12 + */ +/* Bit 15:14, reserved. */ +/* Bit 13:12, reg_mcdi_reldetlmvlockchkmode. + * lmv lock check mode, 0:cur Lmv, 1: cur & (last | next), + * 2: last & cur & next Lmv, default = 1 + */ +/* Bit 11, reserved. */ +/* Bit 10: 8, reg_mcdi_reldetlmvdifmin. + * min mv dif for lmv dif check, default = 1, note: dif between + * reg_mcdi_rel_det_lmv_dif_max and reg_mcdi_rel_det_lmv_dif_min should be; + * 0,1,3,7, not work for others + */ +/* Bit 7: 4, reg_mcdi_reldetlmvdifmax. + * max mv dif for lmv dif check, default = 4 + */ +/* Bit 3: 1, reserved */ +/* Bit 0, reg_mcdi_reldetlmvdifmvmode. + * mv mode used for lmv dif check, 0: use refmv, 1: use qmv, default = 0 + */ +#define MCDI_REL_DET_FRQ_CHK ((0x2f31)) +/* Bit 31:12, reserved. */ +/* Bit 11: 8, reg_mcdi_reldetfrqgain. + * gain for frequency check, normalized to 4 as '1', default = 10 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_reldetfrqmax. + * max value for frequency check, default = 31 + */ +#define MCDI_REL_DET_PD22_CHK ((0x2f32)) +/* Bit 31:18, reserved. */ +/* Bit 17: 8, reg_mcdi_reldetpd22chkoffst. + * offset for pd22 check happened, default = 512 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_reldetpd22chkgain. + * gain for pd22 check happened, normalized to 8 as '1', default = 12 + */ +#define MCDI_REL_DET_RPT_CHK_ROW ((0x2f33)) +/* Bit 31:27, reserved */ +/* Bit 26:16, reg_mcdi_reldetrptchkendrow. + * end row (<) number for repeat check, default = 2047 + */ +/* Bit 15:11, reserved */ +/* Bit 10: 0, reg_mcdi_reldetrptchkstartrow. + * start row (>=) number for repeat check, default = 0 + */ +#define MCDI_REL_DET_RPT_CHK_GAIN_QMV ((0x2f34)) +/* Bit 31:30, reserved */ +/* Bit 29:24, reg_mcdi_reldetrptchkqmvmax. + * max thd (<) of abs qmv for repeat check, default = 15, + * note that quarter mv's range is -63~63 + */ +/* Bit 23:22, reserved */ +/* Bit 21:16, reg_mcdi_reldetrptchkqmvmin. + * min thd (>=) of abs qmv for repeat check, default = 10, + * note that quarter mv's range is -63~63 + */ +/* Bit 15, reserved/ */ +/* Bit 14: 4, reg_mcdi_reldetrptchkoffst. + * offset for repeat check, default = 512 + */ +/* Bit 3: 0, reg_mcdi_reldetrptchkgain. + * gain for repeat check, normalized to 8 as '1', default = 4 + */ +#define MCDI_REL_DET_RPT_CHK_THD_0 ((0x2f35)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_mcdi_reldetrptchkzerosadthd. + * zero sad thd (<) for repeat check, default = 255 + */ +/* Bit 15:14, reserved. */ +/* Bit 13: 8, reg_mcdi_reldetrptchkzerobadwthd. + * zero badw thd (>=) for repeat check, default = 16 + */ +/* Bit 7: 4, reserved */ +/* Bit 3: 0, reg_mcdi_reldetrptchkfrqdifthd. + * frequency dif thd (<) for repeat check, 0~10, default = 5 + */ +#define MCDI_REL_DET_RPT_CHK_THD_1 ((0x2f36)) +/* Bit 31:16, reserved */ +/* Bit 15: 8, reg_mcdi_reldetrptchkvdifthd. + * vertical dif thd (<) for repeat check, default = 16 + */ +/* Bit 7: 0, reg_mcdi_reldetrptchkhdifthd. + * horizontal dif thd (>=) for repeat check, default = 16 + */ +#define MCDI_REL_DET_LPF_DIF_THD ((0x2f37)) +/* Bit 31:24, reg_mcdi_reldetlpfdifthd3. + * hdif thd (<) for lpf selection of horizontal block, default = 9 + */ +/* Bit 23:16, reg_mcdi_reldetlpfdifthd2. + * vdif-hdif thd (>=) for lpf selection of horizontal block, default = 48 + */ +/* Bit 15: 8, reg_mcdi_reldetlpfdifthd1. + * vdif thd (<) for lpf selection of vertical block, default = 9 + */ +/* Bit 7: 0, reg_mcdi_reldetlpfdifthd0. + * hdif-vdif thd (>=) for lpf selection of vertical block, default = 48 + */ +#define MCDI_REL_DET_LPF_MSK_00_03 ((0x2f38)) +/* Bit 31:29, reserved */ +/* Bit 28:24, reg_mcdi_reldetlpfmsk03. + * det lpf mask03 for gmv/lmv locked mode, 0~16, default = 1 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_mcdi_reldetlpfmsk02. + * det lpf mask02 for gmv/lmv locked mode, 0~16, default = 1 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_reldetlpfmsk01. + * det lpf mask01 for gmv/lmv locked mode, 0~16, default = 5 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_reldetlpfmsk00. + * det lpf mask00 for gmv/lmv locked mode, 0~16, default = 8 + */ +#define MCDI_REL_DET_LPF_MSK_04_12 ((0x2f39)) +/* Bit 31:29, reserved */ +/* Bit 28:24, reg_mcdi_reldetlpfmsk12. + * det lpf mask12 for vertical blocks, 0~16, default = 0 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_mcdi_reldetlpfmsk11. + * det lpf mask11 for vertical blocks, 0~16, default = 0 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_reldetlpfmsk10. + * det lpf mask10 for vertical blocks, 0~16, default = 16 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_reldetlpfmsk04. + * det lpf mask04 for gmv/lmv locked mode, 0~16, default = 1 + */ +#define MCDI_REL_DET_LPF_MSK_13_21 ((0x2f3a)) +/* Bit 31:29, reserved */ +/* Bit 28:24, reg_mcdi_reldetlpfmsk21. + * det lpf mask21 for horizontal blocks, 0~16, default = 6 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_mcdi_reldetlpfmsk20. + * det lpf mask20 for horizontal blocks, 0~16, default = 8 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_reldetlpfmsk14. + * det lpf mask14 for vertical blocks, 0~16, default = 0 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_reldetlpfmsk13. + * det lpf mask13 for vertical blocks, 0~16, default = 0 + */ +#define MCDI_REL_DET_LPF_MSK_22_30 ((0x2f3b)) +/* Bit 31:29, reserved */ +/* Bit 28:24, reg_mcdi_reldetlpfmsk30. + * det lpf mask30 for other blocks, 0~16, default = 16 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_mcdi_reldetlpfmsk24. + * det lpf mask24 for horizontal blocks, 0~16, default = 1 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_reldetlpfmsk23. + * det lpf mask23 for horizontal blocks, 0~16, default = 0 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_reldetlpfmsk22. + * det lpf mask22 for horizontal blocks, 0~16, default = 1 + */ +#define MCDI_REL_DET_LPF_MSK_31_34 ((0x2f3c)) +/* Bit 31:29, reserved */ +/* Bit 28:24, reg_mcdi_reldetlpfmsk34. + * det lpf mask34 for other blocks, 0~16, default = 0 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_mcdi_reldetlpfmsk33. + * det lpf mask33 for other blocks, 0~16, default = 0 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_reldetlpfmsk32. + * det lpf mask32 for other blocks, 0~16, default = 0 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_reldetlpfmsk31. + * det lpf mask31 for other blocks, 0~16, default = 0 + */ +/* Note: there are four group lpf masks from addr 37~3b, + * each group sum equal to 16. + */ +#define MCDI_REL_DET_MIN ((0x2f3d)) +/* Bit 31: 7, reserved */ +/* Bit 6: 0, reg_mcdi_reldetmin. + * min of detected value, default = 16 + */ +#define MCDI_REL_DET_LUT_0_3 ((0x2f3e)) +/* Bit 31:24, reg_mcdi_reldetmaplut3. default = 8 */ +/* Bit 23:16, reg_mcdi_reldetmaplut2. default = 4 */ +/* Bit 15: 8, reg_mcdi_reldetmaplut1. default = 2 */ +/* Bit 7: 0, reg_mcdi_reldetmaplut0. default = 0 */ +#define MCDI_REL_DET_LUT_4_7 ((0x2f3f)) +/* Bit 31:24, reg_mcdi_reldetmaplut7. default = 64 */ +/* Bit 23:16, reg_mcdi_reldetmaplut6. default = 48 */ +/* Bit 15: 8, reg_mcdi_reldetmaplut5. default = 32 */ +/* Bit 7: 0, reg_mcdi_reldetmaplut4. default = 16 */ +#define MCDI_REL_DET_LUT_8_11 ((0x2f40)) +/* Bit 31:24, reg_mcdi_reldetmaplut11. default = 160 */ +/* Bit 23:16, reg_mcdi_reldetmaplut10. default = 128 */ +/* Bit 15: 8, reg_mcdi_reldetmaplut9. default = 96 */ +/* Bit 7: 0, reg_mcdi_reldetmaplut8. default = 80 */ +#define MCDI_REL_DET_LUT_12_15 ((0x2f41)) +/* Bit 31:24, reg_mcdi_reldetmaplut15. default = 255 */ +/* Bit 23:16, reg_mcdi_reldetmaplut14. default = 240 */ +/* Bit 15: 8, reg_mcdi_reldetmaplut13. default = 224 */ +/* Bit 7: 0, reg_mcdi_reldetmaplut12. default = 192 */ +#define MCDI_REL_DET_COL_CFD_THD ((0x2f42)) +/* Bit 31:24, reg_mcdi_reldetcolcfdfltthd. + * thd for flat smaller than (<) of column cofidence, default = 5 + */ +/* Bit 23:16, reg_mcdi_reldetcolcfdthd1. + * thd for rel larger than (>=) in rel calc. + * mode col confidence without gmv locking, default = 160 + */ +/* Bit 15: 8, reg_mcdi_reldetcolcfdthd0. + * thd for rel larger than (>=) in rel calc. + * mode col confidence when gmv locked, default = 100 + */ +/* Bit 7: 2, reg_mcdi_reldetcolcfdbadwthd. + * thd for badw larger than (>=) in qbadw calc. + * mode of column cofidence, default = 16 + */ +/* Bit 1, reserved */ +/* Bit 0, reg_mcdi_reldetcolcfdcalcmode. calc. + * mode for column cofidence, 0: use rel, 1: use qbadw, default = 0 + */ +#define MCDI_REL_DET_COL_CFD_AVG_LUMA ((0x2f43)) +/* Bit 31:24, reg_mcdi_reldetcolcfdavgmin1. + * avg luma min1 (>=) for column cofidence, valid between 16~235, default = 235 + */ +/* Bit 23:16, reg_mcdi_reldetcolcfdavgmax1. + * avg luma max1 (<) for column cofidence, valid between 16~235, default = 235 + */ +/* Bit 15: 8, reg_mcdi_reldetcolcfdavgmin0. + * avg luma min0 (>=) for column cofidence, valid between 16~235, default = 16 + */ +/* Bit 7: 0, reg_mcdi_reldetcolcfdavgmax0. + * avg luma max0 (<) for column cofidence, valid between 16~235, default = 21 + */ +#define MCDI_REL_DET_BAD_THD_0 ((0x2f44)) +/* Bit 31:16, reserved */ +/* Bit 15: 8, reg_mcdi_reldetbadsadthd. + * thd (>=) for bad sad, default = 120 (480/4) + */ +/* Bit 7: 6, reserved */ +/* Bit 5: 0, reg_mcdi_reldetbadbadwthd. + * thd (>=) for bad badw, 0~42, default = 12 + */ +#define MCDI_REL_DET_BAD_THD_1 ((0x2f45)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_mcdi_reldetbadrelfltthd. + * thd (>=) of flat for bad rel detection, default = 4 + */ +/* Bit 15: 8, reg_mcdi_reldetbadrelthd1. + * thd (>=) for bad rel without gmv/lmv locked, default = 160 + */ +/* Bit 7: 0, reg_mcdi_reldetbadrelthd0. + * thd (>=) for bad rel with gmv/lmv locked, default = 120 + */ +#define MCDI_PD22_CHK_THD ((0x2f46)) +/* Bit 31:25, reserved */ +/* Bit 24:16, reg_mcdi_pd22chksaddifthd. + * sad dif thd (>=) for (pd22chksad - qsad) for pd22 check, default = 64 + */ +/* Bit 15:14, reserved */ +/* Bit 13: 8, reg_mcdi_pd22chkqmvthd. + * thd (>=) of abs qmv for pd22 check, default = 2 + */ +/* Bit 7: 0, reg_mcdi_pd22chkfltthd. + * thd (>=) of flat for pd22 check, default = 4 + */ +#define MCDI_PD22_CHK_GAIN_OFFST_0 ((0x2f47)) +/* Bit 31:24, reg_mcdi_pd22chkedgeoffst0. + * offset0 of pd22chkedge from right film22 phase, -128~127, default = 0 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_mcdi_pd22chkedgegain0. + * gain0 of pd22chkedge from right film22 phase, + * normalized to 16 as '1', default = 16 + */ +/* Bit 15:12, reserved */ +/* Bit 11: 8, reg_mcdi_pd22chkbadwoffst0. + * offset0 of pd22chkbadw from right film22 phase, -8~7, default = 0 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_pd22chkbadwgain0. + * gain0 of pd22chkbadw from right film22 phase, + * normalized to 16 as '1', default = 8 + */ +#define MCDI_PD22_CHK_GAIN_OFFST_1 ((0x2f48)) +/* Bit 31:24, reg_mcdi_pd22chkedgeoffst1. + * offset1 of pd22chkedge from right film22 phase, -128~127, default = 0 + */ +/* Bit 23:21, reserved */ +/* Bit 20:16, reg_mcdi_pd22chkedgegain1. + * gain1 of pd22chkedge from right film22 phase, + * normalized to 16 as '1', default = 16 + */ +/* Bit 15:12, reserved */ +/* Bit 11: 8, reg_mcdi_pd22chkbadwoffst1. + * offset1 of pd22chkbadw from right film22 phase, -8~7, default = 0 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_pd22chkbadwgain1. + * gain1 of pd22chkbadw from right film22 phase, + * normalized to 16 as '1', default = 12 + */ +#define MCDI_LMV_LOCK_CNT_THD_GAIN ((0x2f49)) +/* Bit 31:20, reserved */ +/* Bit 19:16, reg_mcdi_lmvlockcntmax. + * max lmv lock count number, default = 6 + */ +/* Bit 15:12, reg_mcdi_lmvlockcntoffst. + * offset for lmv lock count, -8~7, default = 0 + */ +/* Bit 11: 8, reg_mcdi_lmvlockcntgain. + * gain for lmv lock count, normalized 8 as '1', 15 is set to 16, default = 8 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_lmvlockcntthd. + * lmv count thd (>=) before be locked, 1~31, default = 4 + */ +#define MCDI_LMV_LOCK_ABS_DIF_THD ((0x2f4a)) +/* Bit 31:27, reserved */ +/* Bit 26:24, reg_mcdi_lmvlockdifthd2. + * lmv dif thd for third part, before locked, default = 1 + */ +/* Bit 23, reserved */ +/* Bit 22:20, reg_mcdi_lmvlockdifthd1. + * lmv dif thd for second part, before locked, default = 1 + */ +/* Bit 19, reserved */ +/* Bit 18:16, reg_mcdi_lmvlockdifthd0. + * lmv dif thd for first part, before locked, default = 1 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_lmvlockabsmax. + * max abs (<) of lmv to be locked, default = 24 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_lmvlockabsmin. + * min abs (>=) of lmv to be locked, default = 1 + */ +#define MCDI_LMV_LOCK_ROW ((0x2f4b)) +/* Bit 31:27, reserved */ +/* Bit 26:16, reg_mcdi_lmvlockendrow. + * end row (<) for lmv lock, default = 2047 + */ +/* Bit 15:11, reserved */ +/* Bit 10: 0, reg_mcdi_lmvlockstartrow. + * start row (>=) for lmv lock, default = 0 + */ +#define MCDI_LMV_LOCK_RT_MODE ((0x2f4c)) +/* Bit 31:27, reserved */ +/* Bit 26:24, reg_mcdi_lmvlockextmode. + * extend lines for lmv lock check, check how many lines + * for lmv locking, default = 2 + */ +/* Bit 23:16, reg_mcdi_lmvlockfltcntrt. + * ratio of flt cnt for lock check, normalized 256 as '1', + * 255 is set to 256, default = 32 + */ +/* Bit 15: 8, reg_mcdi_lmvlocklmvcntrt1. + * ratio when use non-zero lmv for lock check, + * normalized 256 as '1', 255 is set to 256, default = 48 + */ +/* Bit 7: 0, reg_mcdi_lmvlocklmvcntrt0. + * ratio when use max lmv for lock check, normalized 256 as '1', +255 is set to 256, default = 106 +*/ +#define MCDI_GMV_LOCK_CNT_THD_GAIN ((0x2f4d)) +/* Bit 31:20, reserved */ +/* Bit 19:16, reg_mcdi_gmvlockcntmax. + * max gmv lock count number, default = 6 + */ +/* Bit 15:12, reg_mcdi_gmvlockcntoffst. + * offset for gmv lock count, -8~7, default = 0 + */ +/* Bit 11: 8, reg_mcdi_gmvlockcntgain. + * gain for gmv lock count, normalized 8 as '1', 15 is set to 16, default = 8 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_gmvlockcntthd. + * gmv count thd (>=) before be locked, 1~31, default = 4 + */ +#define MCDI_GMV_LOCK_ABS_DIF_THD ((0x2f4e)) +/* Bit 31:27, reserved */ +/* Bit 26:24, reg_mcdi_gmvlockdifthd2. + * gmv dif thd for third part, before locked, default = 3 + */ +/* Bit 23, reserved */ +/* Bit 22:20, reg_mcdi_gmvlockdifthd1. + * gmv dif thd for second part, before locked, default = 2 + */ +/* Bit 19, reserved */ +/* Bit 18:16, reg_mcdi_gmvlockdifthd0. + * gmv dif thd for first part, before locked, default = 1 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_gmvlockabsmax. + * max abs of gmv to be locked, default = 15 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_gmvlockabsmin. + * min abs of gmv to be locked, default = 1 + */ +#define MCDI_HIGH_VERT_FRQ_DIF_THD ((0x2f4f)) +/* Bit 31: 0, reg_mcdi_highvertfrqfldavgdifthd. + * high_vert_frq field average luma dif thd (>=), 3*Blk_Width*Blk_Height, + * set by software, default = 103680 + */ +#define MCDI_HIGH_VERT_FRQ_DIF_DIF_THD ((0x2f50)) +/* Bit 31: 0, reg_mcdi_highvertfrqfldavgdifdifthd. + * high_vert_frq field average luma dif's dif thd (<), 3*Blk_Width*Blk_Height, + * set by software, default = 103680 + */ +#define MCDI_HIGH_VERT_FRQ_RT_GAIN ((0x2f51)) +/* Bit 31:20, reserved */ +/* Bit 19:16, reg_mcdi_highvertfrqcntthd. + * high_vert_frq count thd (>=) before locked, 1~31, default = 4 + */ +/* Bit 15: 8, reg_mcdi_highvertfrqbadsadrt. + * ratio for high_vert_frq bad sad count, normalized 256 as '1', + * 255 is set to 256, default = 24 + */ +/* Bit 7: 0, reg_mcdi_highvertfrqbadbadwrt. + * ratio for high_vert_frq badw count, normalized 256 as '1', + * 255 is set to 256, default = 130 + */ +#define MCDI_MOTION_PARADOX_THD ((0x2f52)) +/* Bit 31:29, reserved */ +/* Bit 28:24, reg_mcdi_motionparadoxcntthd. + * motion paradox count thd (>=) before locked, 1~31, default = 4 + */ +/* Bit 23:22, reserved */ +/* Bit 21:16, reg_mcdi_motionparadoxgmvthd. + * abs gmv thd (<) of motion paradox, 0~32, note that 32 + * means invalid gmv, be careful, default = 32 + */ +/* Bit 15: 0, reserved */ +#define MCDI_MOTION_PARADOX_RT ((0x2f53)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_mcdi_motionparadoxbadsadrt. + * ratio for field bad sad count of motion paradox, + * normalized 256 as '1', 255 is set to 256, default = 24 + */ +/* Bit 15: 8, reg_mcdi_motionparadoxbadrelrt. + * ratio for field bad reliabilty count of motion paradox, + * normalized 256 as '1', 255 is set to 256, default = 120 + */ +/* Bit 7: 0, reg_mcdi_motionparadoxmtnrt. + * ratio for field motion count of motion paradox, + * normalized 256 as '1', 255 is set to 256, default = 218 + */ +#define MCDI_MOTION_REF_THD ((0x2f54)) +/* Bit 31:24, reserved */ +/* Bit 23:20, reg_mcdi_motionrefoffst. + * motion ref additive offset, default = 15 + */ +/* Bit 19:16, reg_mcdi_motionrefgain. + * motion ref gain, normalized 8 as '1', default = 8 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_motionrefrptmvthd. + * abs thd (>=) of rpt mv (0~31, 32 means invalid) for motion ref, default = 1 + */ +/* Bit 7: 2, reg_mcdi_motionrefqmvthd. + * min thd (>=) of abs qmv for motion ref, + * note that quarter mv's range is -63~63, default = 2 + */ +/* Bit 1: 0, reg_mcdi_motionreflpfmode. + * Mv and (8 x repeat flg) 's lpf mode of motion refinement, + * 0: no lpf, 1: [1 2 1], 2: [1 2 2 2 1], default = 1 + */ +#define MCDI_REL_COL_REF_RT ((0x2f55)) +/* Bit 31: 8, reserved */ +/* Bit 7: 0, reg_mcdi_relcolrefrt. + * ratio for column cofidence level against column number, + * for refinement, default = 135 + */ +#define MCDI_PD22_CHK_THD_RT ((0x2f56)) +/* Bit 31:27, reserved */ +/* Bit 26:16, reg_mcdi_pd22chkfltcntrt. + * ratio for flat count of field pulldown 22 check, normalized 2048 as '1', + * 2047 is set to 2048, default = 1 + */ +/* Bit 15: 8, reg_mcdi_pd22chkcntrt. ratio of pulldown 22 check count, + * normalized 256 as '1', 255 is set to 256, default = 100 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_pd22chkcntthd. + * thd (>=) for pd22 count before locked, 1~31, default = 4 + */ +#define MCDI_CHAR_DET_DIF_THD ((0x2f57)) +/* Bit 31:24, reserved */ +/* Bit 23:16, reg_mcdi_chardetminmaxdifthd. + * thd (>=) for dif between min and max value, default = 64 + */ +/* Bit 15: 8, reg_mcdi_chardetmaxdifthd. + * thd (<) for dif between max value, default = 17 + */ +/* Bit 7: 0, reg_mcdi_chardetmindifthd. + * thd (<) for dif between min value, default = 17 + */ +#define MCDI_CHAR_DET_CNT_THD ((0x2f58)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_mcdi_chardettotcntthd. + * thd (>=) for total count, 0~21, default = 18 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_chardetmaxcntthd. + * thd (>=) for max count, 0~21, default = 1 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_chardetmincntthd. + * thd (>=) for min count, 0~21, default = 1 + */ +#define MCDI_FIELD_MV ((0x2f60)) +/* Bit 31:24, reg_mcdi_pd22chkcnt */ +/* Bit 23:16, reg_mcdi_fieldgmvcnt */ +/* Bit 15, reg_mcdi_pd22chkflg */ +/* Bit 14, reg_mcdi_fieldgmvlock */ +/* Bit 13: 8, reg_mcdi_fieldrptmv. last field rpt mv */ +/* Bit 7: 6, reserved */ +/* Bit 5: 0, reg_mcdi_fieldgmv. last field gmv */ +#define MCDI_FIELD_HVF_PRDX_CNT ((0x2f61)) +/* Bit 31:24, reg_mcdi_motionparadoxcnt. */ +/* Bit 23:17, reserved */ +/* Bit 16, reg_mcdi_motionparadoxflg. */ +/* Bit 15: 8, reg_mcdi_highvertfrqcnt. */ +/* Bit 7: 4, reserved */ +/* Bit 3: 2, reg_mcdi_highvertfrqphase. */ +/* Bit 1, reserved */ +/* Bit 0, reg_mcdi_highvertfrqflg. */ +#define MCDI_FIELD_LUMA_AVG_SUM_0 ((0x2f62)) +/* Bit 31: 0, reg_mcdi_fld_luma_avg_sum0. */ +#define MCDI_FIELD_LUMA_AVG_SUM_1 ((0x2f63)) +/* Bit 31: 0, reg_mcdi_fld_luma_avg_sum1. */ +#define MCDI_YCBCR_BLEND_CRTL ((0x2f64)) +/* Bit 31:16, reserved */ +/* Bit 15: 8, reg_mcdi_ycbcrblendgain. + * ycbcr blending gain for cbcr in ycbcr. default = 0 + */ +/* Bit 7: 2, reserved. */ +/* Bit 1: 0, reg_mcdi_ycbcrblendmode. + * 0:y+cmb(cb,cr), 1:med(r,g,b), 2:max(r,g,b), default = 2 + */ +#define MCDI_MCVECWR_CANVAS_SIZE ((0x2f65)) +#define MCDI_MCVECRD_CANVAS_SIZE ((0x2f66)) +#define MCDI_MCINFOWR_CANVAS_SIZE ((0x2f67)) +#define MCDI_MCINFORD_CANVAS_SIZE ((0x2f68)) +#define MCDI_MCVECWR_X ((0x2f92)) +#define MCDI_MCVECWR_Y ((0x2f93)) +#define MCDI_MCVECWR_CTRL ((0x2f94)) +#define MCDI_MCVECRD_X ((0x2f95)) +#define MCDI_MCVECRD_Y ((0x2f96)) +#define MCDI_MCVECRD_CTRL ((0x2f97)) +#define MCDI_MCINFOWR_X ((0x2f98)) +#define MCDI_MCINFOWR_Y ((0x2f99)) +#define MCDI_MCINFOWR_CTRL ((0x2f9a)) +#define MCDI_MCINFORD_X ((0x2f9b)) +#define MCDI_MCINFORD_Y ((0x2f9c)) +#define MCDI_MCINFORD_CTRL ((0x2f9d)) +/* === MC registers ============================================ */ +#define MCDI_MC_CRTL ((0x2f70)) +/* Bit 31: 9, reserved */ +/* Bit 8, reg_mcdi_mcpreflg. + * flag to use previous field for MC, 0:forward field, + * 1: previous field, default = 1 + */ +/* Bit 7, reg_mcdi_mcrelrefbycolcfden. + * enable rel refinement by column cofidence in mc blending, default = 1 + */ +/* Bit 6: 5, reg_mcdi_mclpfen. + * enable mc pixles/rel lpf, 0:disable, 1: lpf rel, + * 2: lpf mc pxls, 3: lpf both rel and mc pxls, default = 0 + */ +/* Bit 4: 2, reg_mcdi_mcdebugmode. + * enable mc debug mode, 0:disable, 1: split left/right, + * 2: split top/bottom, 3: debug mv, 4: debug rel, default = 0 + */ +/* Bit 1: 0, reg_mcdi_mcen. + * mcdi enable mode, 0:disable, 1: blend with ma, 2: full mc, default = 1 + */ +#define MCDI_MC_LPF_MSK_0 ((0x2f71)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_mcdi_mclpfmsk02. + * mc lpf coef. 2 for pixel 0 of current block,normalized 16 as '1', default = 0 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_mclpfmsk01. + * mc lpf coef. 1 for pixel 0 of current block,normalized 16 as '1', default = 9 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_mclpfmsk00. + * mc lpf coef. 0 for pixel 0 of current block,normalized 16 as '1', default = 7 + */ +#define MCDI_MC_LPF_MSK_1 ((0x2f72)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_mcdi_mclpfmsk12. + * mc lpf coef. 2 for pixel 1 of current block, + * 0~16, normalized 16 as '1', default = 0 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_mclpfmsk11. + * mc lpf coef. 1 for pixel 1 of current block, 0~16, + * normalized 16 as '1', default = 11 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_mclpfmsk10. + * mc lpf coef. 0 for pixel 1 of current block, 0~16, + * normalized 16 as '1', default = 5 + */ +#define MCDI_MC_LPF_MSK_2 ((0x2f73)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_mcdi_mclpfmsk22. + * mc lpf coef. 2 for pixel 2 of current block, 0~16, + * normalized 16 as '1', default = 1 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_mclpfmsk21. + * mc lpf coef. 1 for pixel 2 of current block, 0~16, + * normalized 16 as '1', default = 14 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_mclpfmsk20. + * mc lpf coef. 0 for pixel 2 of current block, 0~16, + * normalized 16 as '1', default = 1 + */ +#define MCDI_MC_LPF_MSK_3 ((0x2f74)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_mcdi_mclpfmsk32. + * mc lpf coef. 2 for pixel 3 of current block, 0~16, + * normalized 16 as '1', default = 5 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_mclpfmsk31. + * mc lpf coef. 1 for pixel 3 of current block, 0~16, + * normalized 16 as '1', default = 11 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_mclpfmsk30. + * mc lpf coef. 0 for pixel 3 of current block, 0~16, + * normalized 16 as '1', default = 0 + */ +#define MCDI_MC_LPF_MSK_4 ((0x2f75)) +/* Bit 31:21, reserved */ +/* Bit 20:16, reg_mcdi_mclpfmsk42. + * mc lpf coef. 2 for pixel 4 of current block, 0~16, + * normalized 16 as '1', default = 7 + */ +/* Bit 15:13, reserved */ +/* Bit 12: 8, reg_mcdi_mclpfmsk41. + * mc lpf coef. 1 for pixel 4 of current block, 0~16, + * normalized 16 as '1', default = 9 + */ +/* Bit 7: 5, reserved */ +/* Bit 4: 0, reg_mcdi_mclpfmsk40. + * mc lpf coef. 0 for pixel 4 of current block, 0~16, + * normalized 16 as '1', default = 0 + */ +#define MCDI_MC_REL_GAIN_OFFST_0 ((0x2f76)) +/* Bit 31:26, reserved */ +/* Bit 25, reg_mcdi_mcmotionparadoxflg. + * flag of motion paradox, initial with 0 and read from software, default = 0 + */ +/* Bit 24, reg_mcdi_mchighvertfrqflg. + * flag of high vert frq, initial with 0 and read from software, default = 0 + */ +/* Bit 23:16, reg_mcdi_mcmotionparadoxoffst. + * offset (rel + offset) for rel (MC blending coef.) + * refinement if motion paradox + * detected before MC blending before MC blending, default = 128 + */ +/* Bit 15:12, reserved */ +/* Bit 11: 8, reg_mcdi_mcmotionparadoxgain. + * gain for rel (MC blending coef.) + * refinement if motion paradox detected before MC + * blending, normalized 8 as '1', set 15 to 16, default = 8 + */ +/* Bit 7: 4, reg_mcdi_mchighvertfrqoffst. minus offset + * (alpha - offset) for motion (MA blending coef.) refinement if high vertical + * frequency detected before MA blending, default = 15 + */ +/* Bit 3: 0, reg_mcdi_mchighvertfrqgain. + * gain for motion (MA blending coef.) refinement if high vertical frequency + * detected before MA blending, normalized 8 as '1', set 15 to 16, default = 8 + */ +#define MCDI_MC_REL_GAIN_OFFST_1 ((0x2f77)) +/* Bit 31:24, reg_mcdi_mcoutofboundrayoffst. + * offset (rel + offset) for rel (MC blending coef.) refinement + * if MC pointed out + * of boundray before MC blending before MC blending, default = 255 + */ +/* Bit 23:20, reserved*/ +/* Bit 19:16, reg_mcdi_mcoutofboundraygain. + * gain for rel (MC blending coef.) refinement + * if MC pointed out of boundray before + * MC blending, normalized 8 as '1', set 15 to 16, default = 8 + */ +/* Bit 15: 8, reg_mcdi_mcrelrefbycolcfdoffst. + * offset (rel + offset) for rel (MC blending coef.) refinement + * if motion paradox + * detected before MC blending before MC blending, default = 255 + */ +/* Bit 7: 4, reserved. */ +/* Bit 3: 0, reg_mcdi_mcrelrefbycolcfdgain. + * gain for rel (MC blending coef.) refinement + * if column cofidence failed before MC + * blending, normalized 8 as '1', set 15 to 16, default = 8 + */ +#define MCDI_MC_COL_CFD_0 ((0x2f78)) +/* Bit 31: 0, mcdi_mc_col_cfd_0. + * column cofidence value 0 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_1 ((0x2f79)) +/* Bit 31: 0, mcdi_mc_col_cfd_1. + * column cofidence value 1 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_2 ((0x2f7a)) +/* Bit 31: 0, mcdi_mc_col_cfd_2. + * column cofidence value 2 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_3 ((0x2f7b)) +/* Bit 31: 0, mcdi_mc_col_cfd_3. + * column cofidence value 3 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_4 ((0x2f7c)) +/* Bit 31: 0, mcdi_mc_col_cfd_4. + * column cofidence value 4 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_5 ((0x2f7d)) +/* Bit 31: 0, mcdi_mc_col_cfd_5. + * column cofidence value 5 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_6 ((0x2f7e)) +/* Bit 31: 0, mcdi_mc_col_cfd_6. + * column cofidence value 6 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_7 ((0x2f7f)) +/* Bit 31: 0, mcdi_mc_col_cfd_7. + * column cofidence value 7 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_8 ((0x2f80)) +/* Bit 31: 0, mcdi_mc_col_cfd_8. + * column cofidence value 8 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_9 ((0x2f81)) +/* Bit 31: 0, mcdi_mc_col_cfd_9. + * column cofidence value 9 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_10 ((0x2f82)) +/* Bit 31: 0, mcdi_mc_col_cfd_10. + * column cofidence value 10 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_11 ((0x2f83)) +/* Bit 31: 0, mcdi_mc_col_cfd_11. + * column cofidence value 11 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_12 ((0x2f84)) +/* Bit 31: 0, mcdi_mc_col_cfd_12. + * column cofidence value 12 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_13 ((0x2f85)) +/* Bit 31: 0, mcdi_mc_col_cfd_13. + * column cofidence value 13 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_14 ((0x2f86)) +/* Bit 31: 0, mcdi_mc_col_cfd_14. + * column cofidence value 14 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_15 ((0x2f87)) +/* Bit 31: 0, mcdi_mc_col_cfd_15. + * column cofidence value 15 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_16 ((0x2f88)) +/* Bit 31: 0, mcdi_mc_col_cfd_16. + * column cofidence value 16 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_17 ((0x2f89)) +/* Bit 31: 0, mcdi_mc_col_cfd_17. + * column cofidence value 17 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_18 ((0x2f8a)) +/* Bit 31: 0, mcdi_mc_col_cfd_18. + * column cofidence value 18 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_19 ((0x2f8b)) +/* Bit 31: 0, mcdi_mc_col_cfd_19. + * column cofidence value 19 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_20 ((0x2f8c)) +/* Bit 31: 0, mcdi_mc_col_cfd_20. + * column cofidence value 20 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_21 ((0x2f8d)) +/* Bit 31: 0, mcdi_mc_col_cfd_21. + * column cofidence value 21 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_22 ((0x2f8e)) +/* Bit 31: 0, mcdi_mc_col_cfd_22. + * column cofidence value 22 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_23 ((0x2f8f)) +/* Bit 31: 0, mcdi_mc_col_cfd_23. + * column cofidence value 23 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_24 ((0x2f90)) +/* Bit 31: 0, mcdi_mc_col_cfd_24. + * column cofidence value 24 read from software. initial = 0 + */ +#define MCDI_MC_COL_CFD_25 ((0x2f91)) +/* Bit 31: 0, mcdi_mc_col_cfd_25. + * column cofidence value 25 read from software. initial = 0 + */ +/* ======= PRE RO Registers ==================================== */ +#define MCDI_RO_FLD_LUMA_AVG_SUM ((0x2fa0)) +/* Bit 31: 0, ro_mcdi_fldlumaavgsum. + * block's luma avg sum of current filed (block based). initial = 0 + */ +#define MCDI_RO_GMV_VLD_CNT ((0x2fa1)) +/* Bit 31: 0, ro_mcdi_gmvvldcnt. + * valid gmv's count of pre one filed (block based). initial = 0 + */ +#define MCDI_RO_RPT_FLG_CNT ((0x2fa2)) +/* Bit 31: 0, ro_mcdi_rptflgcnt. + * repeat mv's count of pre one filed (block based). initial = 0 + */ +#define MCDI_RO_FLD_BAD_SAD_CNT ((0x2fa3)) +/* Bit 31: 0, ro_mcdi_fldbadsadcnt. + * bad sad count of whole pre one field (block based). initial = 0 + */ +#define MCDI_RO_FLD_BAD_BADW_CNT ((0x2fa4)) +/* Bit 31: 0, ro_mcdi_fldbadbadwcnt. + * bad badw count of whole pre one field (block based). initial = 0 + */ +#define MCDI_RO_FLD_BAD_REL_CNT ((0x2fa5)) +/* Bit 31: 0, ro_mcdi_fldbadrelcnt. + * bad rel count of whole pre one field (block based). initial = 0 + */ +#define MCDI_RO_FLD_MTN_CNT ((0x2fa6)) +/* Bit 31: 0, ro_mcdi_fldmtncnt. + * motion count of whole pre one field (pixel based). initial = 0 + */ +#define MCDI_RO_FLD_VLD_CNT ((0x2fa7)) +/* Bit 31: 0, ro_mcdi_fldvldcnt. + * valid motion count of whole pre one field (pixel based). initial = 0 + */ +#define MCDI_RO_FLD_PD_22_PRE_CNT ((0x2fa8)) +/* Bit 31: 0, ro_mcdi_fldpd22precnt. + * prevoius pd22 check count of whole pre one field (block based). initial = 0 + */ +#define MCDI_RO_FLD_PD_22_FOR_CNT ((0x2fa9)) +/* Bit 31: 0, ro_mcdi_fldpd22forcnt. + * forward pd22 check count of whole pre one field (block based). initial = 0 + */ +#define MCDI_RO_FLD_PD_22_FLT_CNT ((0x2faa)) +/* Bit 31: 0, ro_mcdi_fldpd22fltcnt. + * flat count (for pd22 check) of whole pre one field (block based). initial = 0 + */ +#define MCDI_RO_HIGH_VERT_FRQ_FLG ((0x2fab)) +/* Bit 31:16, reserved. */ +/* Bit 15: 8, ro_mcdi_highvertfrqcnt. + * high vertical frequency count till prevoius one field. initial = 0 + */ +/* Bit 7: 3, reserved. */ +/* Bit 2: 1, ro_mcdi_highvertfrqphase. + * high vertical frequency phase of prevoius one field. initial = 2 + */ +/* Bit 0, ro_mcdi_highvertfrqflg. + * high vertical frequency flag of prevoius one field. initial = 0 + */ +#define MCDI_RO_GMV_LOCK_FLG ((0x2fac)) +/* Bit 31:16, reserved. */ +/* Bit 15: 8, ro_mcdi_gmvlckcnt. + * global mv lock count till prevoius one field. initial = 0 + */ +/* Bit 7: 2, ro_mcdi_gmv. + * global mv of prevoius one field. -31~31, initial = 32 (invalid value) + */ +/* Bit 1, ro_mcdi_zerogmvlckflg. + * zero global mv lock flag of prevoius one field. initial = 0 + */ +/* Bit 0, ro_mcdi_gmvlckflg. + * global mv lock flag of prevoius one field. initial = 0 + */ +#define MCDI_RO_RPT_MV ((0x2fad)) +/* Bit 5: 0, ro_mcdi_rptmv. + * repeate mv of prevoius one field. -31~31, initial = 32 (invalid value) + */ +#define MCDI_RO_MOTION_PARADOX_FLG ((0x2fae)) +/* Bit 31:16, reserved. */ +/* Bit 15: 8, ro_mcdi_motionparadoxcnt. + * motion paradox count till prevoius one field. initial = 0 + */ +/* Bit 7: 1, reserved. */ +/* Bit 0, ro_mcdi_motionparadoxflg. + * motion paradox flag of prevoius one field. initial = 0 + */ +#define MCDI_RO_PD_22_FLG ((0x2faf)) +/* Bit 31:16, reserved. */ +/* Bit 15: 8, ro_mcdi_pd22cnt. + * pull down 22 count till prevoius one field. initial = 0 + */ +/* Bit 7: 1, reserved. */ +/* Bit 0, ro_mcdi_pd22flg. + * pull down 22 flag of prevoius one field. initial = 0 + */ +#define MCDI_RO_COL_CFD_0 ((0x2fb0)) +/* Bit 31: 0, ro_mcdi_col_cfd_0. + * column cofidence value 0. initial = 0 + */ +#define MCDI_RO_COL_CFD_1 ((0x2fb1)) +/* Bit 31: 0, ro_mcdi_col_cfd_1. + * column cofidence value 1. initial = 0 + */ +#define MCDI_RO_COL_CFD_2 ((0x2fb2)) +/* Bit 31: 0, ro_mcdi_col_cfd_2. + * column cofidence value 2. initial = 0 + */ +#define MCDI_RO_COL_CFD_3 ((0x2fb3)) +/* Bit 31: 0, ro_mcdi_col_cfd_3. + * column cofidence value 3. initial = 0 + */ +#define MCDI_RO_COL_CFD_4 ((0x2fb4)) +/* Bit 31: 0, ro_mcdi_col_cfd_4. + * column cofidence value 4. initial = 0 + */ +#define MCDI_RO_COL_CFD_5 ((0x2fb5)) +/* Bit 31: 0, ro_mcdi_col_cfd_5. + * column cofidence value 5. initial = 0 + */ +#define MCDI_RO_COL_CFD_6 ((0x2fb6)) +/* Bit 31: 0, ro_mcdi_col_cfd_6. column cofidence value 6. initial = 0 */ +#define MCDI_RO_COL_CFD_7 ((0x2fb7)) +/* Bit 31: 0, ro_mcdi_col_cfd_7. column cofidence value 7. initial = 0 */ +#define MCDI_RO_COL_CFD_8 ((0x2fb8)) +/* Bit 31: 0, ro_mcdi_col_cfd_8. column cofidence value 8. initial = 0 */ +#define MCDI_RO_COL_CFD_9 ((0x2fb9)) +/* Bit 31: 0, ro_mcdi_col_cfd_9. column cofidence value 9. initial = 0 */ +#define MCDI_RO_COL_CFD_10 ((0x2fba)) +/* Bit 31: 0, ro_mcdi_col_cfd_10. column cofidence value 10. initial = 0 */ +#define MCDI_RO_COL_CFD_11 ((0x2fbb)) +/* Bit 31: 0, ro_mcdi_col_cfd_11. column cofidence value 11. initial = 0 */ +#define MCDI_RO_COL_CFD_12 ((0x2fbc)) +/* Bit 31: 0, ro_mcdi_col_cfd_12. column cofidence value 12. initial = 0 */ +#define MCDI_RO_COL_CFD_13 ((0x2fbd)) +/* Bit 31: 0, ro_mcdi_col_cfd_13. column cofidence value 13. initial = 0 */ +#define MCDI_RO_COL_CFD_14 ((0x2fbe)) +/* Bit 31: 0, ro_mcdi_col_cfd_14. column cofidence value 14. initial = 0 */ +#define MCDI_RO_COL_CFD_15 ((0x2fbf)) +/* Bit 31: 0, ro_mcdi_col_cfd_15. column cofidence value 15. initial = 0 */ +#define MCDI_RO_COL_CFD_16 ((0x2fc0)) +/* Bit 31: 0, ro_mcdi_col_cfd_16. column cofidence value 16. initial = 0 */ +#define MCDI_RO_COL_CFD_17 ((0x2fc1)) +/* Bit 31: 0, ro_mcdi_col_cfd_17. column cofidence value 17. initial = 0 */ +#define MCDI_RO_COL_CFD_18 ((0x2fc2)) +/* Bit 31: 0, ro_mcdi_col_cfd_18. column cofidence value 18. initial = 0 */ +#define MCDI_RO_COL_CFD_19 ((0x2fc3)) +/* Bit 31: 0, ro_mcdi_col_cfd_19. column cofidence value 19. initial = 0 */ +#define MCDI_RO_COL_CFD_20 ((0x2fc4)) +/* Bit 31: 0, ro_mcdi_col_cfd_20. column cofidence value 20. initial = 0 */ +#define MCDI_RO_COL_CFD_21 ((0x2fc5)) +/* Bit 31: 0, ro_mcdi_col_cfd_21. column cofidence value 21. initial = 0 */ +#define MCDI_RO_COL_CFD_22 ((0x2fc6)) +/* Bit 31: 0, ro_mcdi_col_cfd_22. column cofidence value 22. initial = 0 */ +#define MCDI_RO_COL_CFD_23 ((0x2fc7)) +/* Bit 31: 0, ro_mcdi_col_cfd_23. column cofidence value 23. initial = 0 */ +#define MCDI_RO_COL_CFD_24 ((0x2fc8)) +/* Bit 31: 0, ro_mcdi_col_cfd_24. column cofidence value 24. initial = 0 */ +#define MCDI_RO_COL_CFD_25 ((0x2fc9)) +/* Bit 31: 0, ro_mcdi_col_cfd_25. column cofidence value 25. initial = 0 */ + + +#define DIPD_COMB_CTRL0 0x2fd0 +/* Bit 31: 24, cmb_v_dif_min */ +/* Bit 23: 16, cmb_v_dif_max */ +/* Bit 15: 8, cmb_crg_mi */ +/* Bit 7: 0, cmb_crg_max */ +#define DIPD_COMB_CTRL1 0x2fd1 +/* Bit 31: 31, pd_check_en */ +/* Bit 29: 24, cmb_wv_min3 */ +/* Bit 21: 16, cmb_wv_min2 */ +/* Bit 13: 8, cmb_wv_min1 */ +/* Bit 5: 0, cmb_wv_min0 */ +#define DIPD_COMB_CTRL2 0x2fd2 +/* Bit 31: 28, cmb_wnd_cnt1 */ +/* Bit 25: 20, ccnt_cmmin1 */ +/* Bit 19: 16, ccnt_mtmin */ +/* Bit 13: 8, ccnt_cmmin */ +/* Bit 5: 0, cmb_wv_min4 */ +#define DIPD_COMB_CTRL3 0x2fd3 +/* Bit 31: 31, cmb32spcl */ +/* Bit 17: 12, cmb_wnd_mthd */ +/* Bit 11: 4, cmb_abs_nocmb */ +/* Bit 3: 0, cnt_minlen */ +#define DIPD_COMB_CTRL4 0x2fd4 +/* Bit 30: 30, flm_stamtn_en */ +/* Bit 29: 28, in_horflt */ +/* Bit 27: 20, alpha */ +/* Bit 19: 16, thtran_ctmtd */ +/* Bit 15: 8, htran_mnth1 */ +/* Bit 7: 0, htran_mnth0 */ +#define DIPD_COMB_CTRL5 0x2fd5 +/* Bit 31: 24, fld_mindif */ +/* Bit 23: 16, frm_mindif */ +/* Bit 13: 8, flm_smp_mtn_cnt */ +/* Bit 7: 0, flm_smp_mtn_thd */ +#define DIPD_RO_COMB_0 0x2fd6 +#define DIPD_RO_COMB_1 0x2fd7 +#define DIPD_RO_COMB_2 0x2fd8 +#define DIPD_RO_COMB_3 0x2fd9 +#define DIPD_RO_COMB_4 0x2fda +#define DIPD_RO_COMB_5 0x2fdb +#define DIPD_RO_COMB_6 0x2fdc +#define DIPD_RO_COMB_7 0x2fdd +#define DIPD_RO_COMB_8 0x2fde +#define DIPD_RO_COMB_9 0x2fdf +#define DIPD_RO_COMB_10 0x2fe0 +#define DIPD_RO_COMB_11 0x2fe1 +#define DIPD_RO_COMB_12 0x2fe2 +#define DIPD_RO_COMB_13 0x2fe3 +#define DIPD_RO_COMB_14 0x2fe4 +#define DIPD_RO_COMB_15 0x2fe5 +#define DIPD_RO_COMB_16 0x2fe6 +#define DIPD_RO_COMB_17 0x2fe7 +#define DIPD_RO_COMB_18 0x2fe8 +#define DIPD_RO_COMB_19 0x2fe9 +#define DIPD_RO_COMB_20 0x2fea +/* nr3 */ +#define NR3_MODE 0x2ff0 + /* d010bfc0 */ +#define NR3_COOP_PARA 0x2ff1 +#define NR3_CNOOP_GAIN 0x2ff2 +#define NR3_YMOT_PARA 0x2ff3 +#define NR3_CMOT_PARA 0x2ff4 +#define NR3_SUREMOT_YGAIN 0x2ff5 +#define NR3_SUREMOT_CGAIN 0x2ff6 + +#endif diff --git a/drivers/amlogic/media/deinterlace/tffbff_check.c b/drivers/amlogic/media/deinterlace/tffbff_check.c new file mode 100644 index 000000000000..135c7ded9876 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/tffbff_check.c @@ -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 +#include +#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); diff --git a/drivers/amlogic/media/deinterlace/vof_soft_top.c b/drivers/amlogic/media/deinterlace/vof_soft_top.c new file mode 100644 index 000000000000..a448bd6189e0 --- /dev/null +++ b/drivers/amlogic/media/deinterlace/vof_soft_top.c @@ -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 +#include + +#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; +} + diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h index eca204d484d5..9b3e6b7671dc 100644 --- a/include/linux/amlogic/media/vfm/vframe.h +++ b/include/linux/amlogic/media/vfm/vframe.h @@ -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,