From: Jihong Sui Date: Mon, 5 Aug 2019 06:17:07 +0000 (+0800) Subject: deinterlace: add di-multi folder v2 [2/3] X-Git-Tag: hardkernel-4.9.236-104~772 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b391eea3dbb159c2ef441996b630a01438376823;p=platform%2Fkernel%2Flinux-amlogic.git deinterlace: add di-multi folder v2 [2/3] PD#SWPL-10064 Problem: add di-multi folder Solution: 1. add di_multi folder; 2. it can be enable by dts; 3. only one of di can be enabled at the same time; 4. no di-pq filse; Verify: U212 Change-Id: I8726d2430cf1beb58d0cd37c0358b7ea8e06c414 Signed-off-by: Jihong Sui --- diff --git a/MAINTAINERS b/MAINTAINERS index 6b64651..2e0f76a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -15104,3 +15104,7 @@ AMLOGIC DEINTERLACE DRIVER M: Jihong Sui F: drivers/amlogic/media/deinterlace/di_pqa.h F: drivers/amlogic/media/di_local/* + +AMLOGIC ADD DI_MULTI DRIVER +M: Jihong Sui +F: drivers/amlogic/media/di_multi/* diff --git a/drivers/amlogic/media/Kconfig b/drivers/amlogic/media/Kconfig index 46220fa..6159286a 100644 --- a/drivers/amlogic/media/Kconfig +++ b/drivers/amlogic/media/Kconfig @@ -89,6 +89,7 @@ source "drivers/amlogic/media/vout/Kconfig" source "drivers/amlogic/media/osd/Kconfig" source "drivers/amlogic/media/osd_ext/Kconfig" source "drivers/amlogic/media/deinterlace/Kconfig" +source "drivers/amlogic/media/di_multi/Kconfig" source "drivers/amlogic/media/di_local/Kconfig" source "drivers/amlogic/media/vin/Kconfig" source "drivers/amlogic/media/video_processor/Kconfig" diff --git a/drivers/amlogic/media/Makefile b/drivers/amlogic/media/Makefile index c72ece4..fe43ed7 100644 --- a/drivers/amlogic/media/Makefile +++ b/drivers/amlogic/media/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_AMLOGIC_MEDIA_FB) += osd/ obj-$(CONFIG_AMLOGIC_MEDIA_FB_EXT) += osd_ext/ obj-$(CONFIG_AMLOGIC_VOUT) += vout/ obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += deinterlace/ +obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += di_multi/ obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += di_local/ obj-$(CONFIG_AMLOGIC_MEDIA_VIN) += vin/ obj-$(CONFIG_AMLOGIC_MEDIA_VIDEO_PROCESSOR) += video_processor/ diff --git a/drivers/amlogic/media/di_multi/Kconfig b/drivers/amlogic/media/di_multi/Kconfig new file mode 100644 index 0000000..8670046 --- /dev/null +++ b/drivers/amlogic/media/di_multi/Kconfig @@ -0,0 +1,15 @@ +# +# Deinterlace driver configuration +# + +menu "DI_MULTI driver" + +config AMLOGIC_MEDIA_DEINTERLACE + tristate "DI_MULTI driver" + default n + help + Select to enable AMLOGIC DEINTERLACE driver + process interlace source need three continueed fields, + wave progressive source with two interlace fields from + one progreesive fields +endmenu diff --git a/drivers/amlogic/media/di_multi/Makefile b/drivers/amlogic/media/di_multi/Makefile new file mode 100644 index 0000000..23df552 --- /dev/null +++ b/drivers/amlogic/media/di_multi/Makefile @@ -0,0 +1,34 @@ +# # Makefile for the Post Process Manager device # +ifeq ($(TARGET_BUILD_VARIANT),userdebug) +ccflags-y := -D DEBUG_SUPPORT +ccflags-y := -DDEBUG +else +ccflags-y := -DDEBUG +endif +ccflags-y += -I. +CFLAGS_dim.o := -I$(src) +obj-$(CONFIG_AMLOGIC_MEDIA_DEINTERLACE) += dim.o +dim-objs += deinterlace.o +dim-objs += deinterlace_hw.o +#dim-objs += deinterlace_mtn.o +dim-objs += deinterlace_dbg.o +#dim-objs += nr_drv.o +#dim-objs += pulldown_drv.o +#dim-objs += detect3d.o +dim-objs += nr_downscale.o +dim-objs += di_pps.o +dim-objs += di_vframe.o +dim-objs += di_prc.o +dim-objs += di_pre.o +dim-objs += di_post.o +dim-objs += di_reg_tab.o +dim-objs += di_dbg.o +dim-objs += di_que.o +dim-objs += di_sys.o +dim-objs += di_task.o +dim-objs += di_api.o +#dim-objs += film_mode_fmw/vof_soft_top.o +#dim-objs += film_mode_fmw/flm_mod_xx.o +#dim-objs += film_mode_fmw/film_fw1.o +ccflags-y += -Idrivers/amlogic/media/common/rdma/ +ccflags-y += -I$(src) \ No newline at end of file diff --git a/drivers/amlogic/media/di_multi/deinterlace.c b/drivers/amlogic/media/di_multi/deinterlace.c new file mode 100644 index 0000000..daa6e1a --- /dev/null +++ b/drivers/amlogic/media/di_multi/deinterlace.c @@ -0,0 +1,8401 @@ +/* + * drivers/amlogic/media/di_multi/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 +#include "register.h" +#include "deinterlace.h" +#include "deinterlace_dbg.h" +#include "nr_downscale.h" + +#include "di_data_l.h" +#include "di_dbg.h" +#include "di_pps.h" +#include "di_pre.h" +#include "di_prc.h" +#include "di_task.h" +#include "di_vframe.h" +#include "di_que.h" +#include "di_api.h" +#include "di_sys.h" + +/*2018-07-18 add debugfs*/ +#include +#include +/*2018-07-18 -----------*/ + +#ifdef DET3D +#include "detect3d.h" +#endif +#define ENABLE_SPIN_LOCK_ALWAYS + +static DEFINE_SPINLOCK(di_lock2); + +#define di_lock_irqfiq_save(irq_flag) \ + spin_lock_irqsave(&di_lock2, irq_flag) + +#define di_unlock_irqfiq_restore(irq_flag) \ + spin_unlock_irqrestore(&di_lock2, irq_flag) + +#ifdef SUPPORT_MPEG_TO_VDIN +static int mpeg2vdin_flag; +static int mpeg2vdin_en; +#endif + +static int di_reg_unreg_cnt = 40; +static bool overturn; + +int dim_get_reg_unreg_cnt(void) +{ + return di_reg_unreg_cnt; +} + +static bool mc_mem_alloc; + +static unsigned int di_pre_rdma_enable; + +/************************************** + * + * + *************************************/ +unsigned int di_dbg = DBG_M_EVENT; +module_param(di_dbg, uint, 0664); +MODULE_PARM_DESC(di_dbg, "debug print"); + +/* destroy unnecessary frames before display */ +static unsigned int hold_video; + +DEFINE_SPINLOCK(plist_lock); + +static const char version_s[] = "2019-04-25ma"; + +/*1:enable bypass pre,ei only; + * 2:debug force bypass pre,ei for post + */ +static int bypass_pre; + +static int invert_top_bot; + +/* 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 support nr10bit, 1: support nr10bit */ +/*static unsigned int nr10bit_support;*/ + +#ifdef RUN_DI_PROCESS_IN_IRQ +/* + * di_process() run in irq, + * dim_reg_process(), dim_unreg_process() run in kernel thread + * dim_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 + */ + +static int input2pre; +/*false:process progress by field; + * true: process progress by frame with 2 interlace buffer + */ +static int input2pre_buf_miss_count; +static int input2pre_proc_miss_count; +static int input2pre_throw_count; +static int input2pre_miss_policy; +/* 0, do not force pre_de_busy to 0, use di_wr_buf after dim_irq happen; + * 1, force pre_de_busy to 0 and call + * dim_pre_de_done_buf_clear to clear di_wr_buf + */ +#endif +/*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; + */ +/*static int use_2_interlace_buff;*/ +/* 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) \ + (((dimp_get(eDI_MP_prog_proc_config) & 0x30) == 0x20) && \ + (((vframe)->type & VIDTYPE_VIU_422) == 0)) + +static int frame_count; +static int disp_frame_count; +int di_get_disp_cnt(void) +{ + return disp_frame_count; +} + +static unsigned long reg_unreg_timeout_cnt; +#ifdef DET3D +static unsigned int det3d_mode; +static void set3d_view(enum tvin_trans_fmt trans_fmt, struct vframe_s *vf); +#endif + +static void di_pq_parm_destroy(struct di_pq_parm_s *pq_ptr); +static struct di_pq_parm_s *di_pq_parm_create(struct am_pq_parm_s *); + +static unsigned int unreg_cnt;/*cnt for vframe unreg*/ +static unsigned int reg_cnt;/*cnt for vframe reg*/ + +static unsigned char recovery_flag; + +static unsigned int recovery_log_reason; +static unsigned int recovery_log_queue_idx; +static struct di_buf_s *recovery_log_di_buf; + +unsigned char dim_vcry_get_flg(void) +{ + return recovery_flag; +} + +void dim_vcry_flg_inc(void) +{ + recovery_flag++; +} + +void dim_vcry_set_flg(unsigned char val) +{ + recovery_flag = val; +} + +void dim_reg_timeout_inc(void) +{ + reg_unreg_timeout_cnt++; +} + +/********************************/ +unsigned int dim_vcry_get_log_reason(void) +{ + return recovery_log_reason; +} + +void dim_vcry_set_log_reason(unsigned int val) +{ + recovery_log_reason = val; +} + +/********************************/ +unsigned char dim_vcry_get_log_q_idx(void) +{ + return recovery_log_queue_idx; +} + +void dim_vcry_set_log_q_idx(unsigned int val) +{ + recovery_log_queue_idx = val; +} + +/********************************/ +struct di_buf_s **dim_vcry_get_log_di_buf(void) +{ + return &recovery_log_di_buf; +} + +void dim_vcry_set_log_di_buf(struct di_buf_s *di_bufp) +{ + recovery_log_di_buf = di_bufp; +} + +void dim_vcry_set(unsigned int reason, unsigned int idx, + struct di_buf_s *di_bufp) +{ + recovery_log_reason = reason; + recovery_log_queue_idx = idx; + recovery_log_di_buf = di_bufp; +} + +static long same_field_top_count; +static long same_field_bot_count; +/* bit 0: + * 0, keep 3 buffers in pre_ready_list for checking; + * 1, keep 4 buffers in pre_ready_list for checking; + */ + +static struct queue_s *get_queue_by_idx(unsigned int channel, int idx); +static void dump_state(unsigned int channel); +static void recycle_keep_buffer(unsigned int channel); + +#define DI_PRE_INTERVAL (HZ / 100) + +/* + * 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 struct di_buf_s *cur_post_ready_di_buf; + +/************For Write register**********************/ + +static unsigned int num_di_stop_reg_addr = 4; +static unsigned int di_stop_reg_addr[4] = {0}; + +static unsigned int is_need_stop_reg(unsigned int addr) +{ + int idx = 0; + + if (dimp_get(eDI_MP_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 dim_DI_Wr(unsigned int addr, unsigned int val) +{ + if (is_need_stop_reg(addr)) + return; + ddbg_reg_save(addr, val, 0, 32); + Wr(addr, val); +} + +void dim_DI_Wr_reg_bits(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len) +{ + if (is_need_stop_reg(adr)) + return; + ddbg_reg_save(adr, val, start, len); /*ary add for debug*/ + Wr_reg_bits(adr, val, start, len); +} + +void dim_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val) +{ + if (is_need_stop_reg(addr)) + return; + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) + dim_DI_Wr(addr, val); + else + VSYNC_WR_MPEG_REG(addr, val); +} + +void dim_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, unsigned int val, + unsigned int start, unsigned int len) +{ + if (is_need_stop_reg(addr)) + return; + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) + dim_DI_Wr_reg_bits(addr, val, start, len); + else + VSYNC_WR_MPEG_REG_BITS(addr, val, start, len); +} + +#ifdef DI_V2 +unsigned int DI_POST_REG_RD(unsigned int addr) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (IS_ERR_OR_NULL(de_devp)) + return 0; + if (de_devp->flags & DI_SUSPEND_FLAG) { + PR_ERR("REG 0x%x access prohibited.\n", addr); + return 0; + } + return VSYNC_RD_MPEG_REG(addr); +} +EXPORT_SYMBOL(DI_POST_REG_RD); + +int DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (IS_ERR_OR_NULL(de_devp)) + return 0; + if (de_devp->flags & DI_SUSPEND_FLAG) { + PR_ERR("REG 0x%x access prohibited.\n", adr); + return -1; + } + return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len); +} +EXPORT_SYMBOL(DI_POST_WR_REG_BITS); +#else +unsigned int l_DI_POST_REG_RD(unsigned int addr) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (IS_ERR_OR_NULL(de_devp)) + return 0; + if (de_devp->flags & DI_SUSPEND_FLAG) { + PR_ERR("REG 0x%x access prohibited.\n", addr); + return 0; + } + return VSYNC_RD_MPEG_REG(addr); +} + +int l_DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (IS_ERR_OR_NULL(de_devp)) + return 0; + if (de_devp->flags & DI_SUSPEND_FLAG) { + PR_ERR("REG 0x%x access prohibited.\n", adr); + return -1; + } + return VSYNC_WR_MPEG_REG_BITS(adr, val, start, len); +} + +#endif +/**********************************/ + +/***************************** + * di attr management : + * enable + * mode + * reg + ******************************/ +/*config attr*/ + +int pre_run_flag = DI_RUN_FLAG_RUN; +static int dump_state_flag; + +const char *dim_get_version_s(void) +{ + return version_s; +} + +int dim_get_blocking(void) +{ + return di_blocking; +} + +unsigned long dim_get_reg_unreg_timeout_cnt(void) +{ + return reg_unreg_timeout_cnt; +} + +struct di_buf_s *dim_get_recovery_log_di_buf(void) +{ + return recovery_log_di_buf; +} + +struct vframe_s **dim_get_vframe_in(unsigned int ch) +{ + return get_vframe_in(ch); +} + +int dim_get_dump_state_flag(void) +{ + return dump_state_flag; +} + +/*--------------------------*/ + +ssize_t +store_dbg(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned int channel = get_current_channel(); /* debug only*/ + struct di_buf_s *pbuf_local = get_buf_local(channel); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + + 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; + dim_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; + dim_dump_vframe(vf); + } else if (strncmp(buf, "pool", 4) == 0) { + unsigned long idx = 0; + + if (kstrtoul(buf + 4, 10, &idx)) + return count; + dim_dump_pool(get_queue_by_idx(channel, idx)); + } else if (strncmp(buf, "state", 4) == 0) { + dump_state(channel); + pr_info("add new debugfs: cat /sys/kernel/debug/di/state\n"); + } else if (strncmp(buf, "prog_proc_config", 16) == 0) { + if (buf[16] == '1') + dimp_set(eDI_MP_prog_proc_config, 1); + else + dimp_set(eDI_MP_prog_proc_config, 0); + } else if (strncmp(buf, "init_flag", 9) == 0) { + if (buf[9] == '1') + set_init_flag(0, true);/*init_flag = 1;*/ + else + set_init_flag(0, false);/*init_flag = 0;*/ + } 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) { + pr_info("add new debugfs: cat /sys/kernel/debug/di/dumpreg\n"); + } else if (strncmp(buf, "dumpmif", 7) == 0) { + dim_dump_mif_size_state(ppre, ppost); + } else if (strncmp(buf, "recycle_buf", 11) == 0) { + recycle_keep_buffer(channel); + } else if (strncmp(buf, "recycle_post", 12) == 0) { + if (di_vf_l_peek(channel)) + di_vf_l_put(di_vf_l_get(channel), channel); + } else if (strncmp(buf, "mem_map", 7) == 0) { + dim_dump_buf_addr(pbuf_local, MAX_LOCAL_BUF_NUM * 2); + } else { + pr_info("DI no support cmd %s!!!\n", buf); + } + + return count; +} + +#ifdef ARY_TEMP +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 + +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 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 + +static 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; */ +int dim_print(const char *fmt, ...) +{ + va_list args; + int avail = PRINT_TEMP_BUF_SIZE; + char buf[PRINT_TEMP_BUF_SIZE]; + int pos, len = 0; + + if (dimp_get(eDI_MP_di_printk_flag) & 1) { + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_PRECISE_TIMESTAMP) + pr_dbg("%llums:", cur_to_msecs()); + 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 (dimp_get(eDI_MP_di_log_flag) & DI_LOG_TIMESTAMP) + len += snprintf(buf + len, avail - len, "%u:", + jiffies_to_msecs(jiffies_64)); + + 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("dim_print:%d %d\n", di_log_wr_pos, di_log_rd_pos); */ + return pos; +} + +ssize_t dim_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; +} + +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; + + dimp_set(eDI_MP_di_printk_flag, tmp); + } else { + dim_print("%s", buf); + } + return 16; +} + +ssize_t +show_vframe_status(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret = 0; + int get_ret = 0; + + struct vframe_states states; + int ch; + struct di_mng_s *pbm = get_bufmng(); + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + if (!pbm->sub_act_flg[ch]) + continue; + else + ret += sprintf(buf + ret, "ch[%d]\n", ch); + + get_ret = vf_get_states_by_name(di_rev_name[ch], &states); + + if (get_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; +} + +/*************************** + * di buffer management + ***************************/ + +static const char * const vframe_type_name[] = { + "", "di_buf_in", "di_buf_loc", "di_buf_post" +}; + +const char *dim_get_vfm_type_name(unsigned int nub) +{ + if (nub < 4) + return vframe_type_name[nub]; + + return ""; +} + +static unsigned int default_width = 1920; +static unsigned int default_height = 1080; + +/* + * 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) + */ + +/*move to deinterlace .h #define queue_t struct queue_s*/ + +static struct queue_s *get_queue_by_idx(unsigned int channel, int idx) +{ + struct queue_s *pqueue = get_queue(channel); + + if (idx < QUEUE_NUM) + return &pqueue[idx]; + else + return NULL; +} + +struct di_buf_s *dim_get_buf(unsigned int channel, int queue_idx, + int *start_pos) +{ + struct queue_s *pqueue = get_queue(channel); + queue_t *q = &pqueue[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; + struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel); + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) + dim_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 < pbuf_pool[pool_idx].size) + di_buf = + &(pbuf_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_ERR("%s:(%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 (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) { + if (di_buf) + dim_print("%s: %x(%d,%d)\n", __func__, di_buf, + pool_idx, di_buf_idx); + else + dim_print("%s: %x\n", __func__, di_buf); + } + + return di_buf; +} + +/*--------------------------*/ +u8 *dim_vmap(ulong addr, u32 size, bool *bflg) +{ + u8 *vaddr = NULL; + ulong phys = addr; + u32 offset = phys & ~PAGE_MASK; + u32 npages = PAGE_ALIGN(size) / PAGE_SIZE; + struct page **pages = NULL; + pgprot_t pgprot; + int i; + + if (!PageHighMem(phys_to_page(phys))) + return phys_to_virt(phys); + + if (offset) + npages++; + + pages = vmalloc(sizeof(struct page *) * npages); + if (!pages) + return NULL; + + for (i = 0; i < npages; i++) { + pages[i] = phys_to_page(phys); + phys += PAGE_SIZE; + } + + /*nocache*/ + pgprot = pgprot_writecombine(PAGE_KERNEL); + + vaddr = vmap(pages, npages, VM_MAP, pgprot); + if (!vaddr) { + PR_ERR("the phy(%lx) vmaped fail, size: %d\n", + addr - offset, npages << PAGE_SHIFT); + vfree(pages); + return NULL; + } + + vfree(pages); +#if 0 + if (debug_mode & 0x20) { + dim_print("[HIGH-MEM-MAP] %s, pa(%lx) to va(%p), size: %d\n", + __func__, addr, vaddr + offset, + npages << PAGE_SHIFT); + } +#endif + *bflg = true; + + return vaddr + offset; +} + +void dim_unmap_phyaddr(u8 *vaddr) +{ + void *addr = (void *)(PAGE_MASK & (ulong)vaddr); + + vunmap(addr); +} + +/*--------------------------*/ +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, dump_adr = 0; + struct di_buf_s *di_buf = NULL; + struct vframe_s *post_vf = NULL; + char *buf_orig, *ps, *token; + char *parm[5] = { NULL }; + char delim1[3] = " "; + char delim2[2] = "\n"; + struct file *filp = NULL; + loff_t pos = 0; + void *buff = NULL; + mm_segment_t old_fs; + bool bflg_vmap = false; + unsigned int channel = get_current_channel();/* debug only*/ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + /*ary add 2019-07-2 being*/ + unsigned int indx; + struct di_buf_s *pbuf_post; + struct di_buf_s *pbuf_local; + struct di_post_stru_s *ppost; + struct di_mm_s *mm = dim_mm_get();/*mm-0705*/ + /*************************/ + + buf_orig = kstrdup(buf, GFP_KERNEL); + ps = buf_orig; + strcat(delim1, delim2); + while (1) { + token = strsep(&ps, delim1); + if (!token) + break; + if (*token == '\0') + continue; + parm[n++] = token; + } + if (strcmp(parm[0], "capture") == 0) { + di_buf = ppre->di_mem_buf_dup_p; + } else if (strcmp(parm[0], "c_post") == 0) { + /*ary add 2019-07-2*/ + if (kstrtouint(parm[2], 0, &channel)) { + PR_ERR("c_post:ch is not number\n"); + kfree(buf_orig); + return 0; + } + if (kstrtouint(parm[3], 0, &indx)) { + PR_ERR("c_post:ch is not number\n"); + kfree(buf_orig); + return 0; + } + di_pr_info("c_post:ch[%d],index[%d]\n", channel, indx); + + ppre = get_pre_stru(channel); + ppost = get_post_stru(channel); + /*mm-0705 if (indx >= ppost->di_post_num) {*/ + if (indx >= mm->sts.num_post) { + PR_ERR("c_post:index is overflow:%d[%d]\n", indx, + mm->sts.num_post); + kfree(buf_orig); + return 0; + } + pbuf_post = get_buf_post(channel); + di_buf = &pbuf_post[indx]; + } else if (strcmp(parm[0], "c_local") == 0) { + /*ary add 2019-07-2*/ + if (kstrtouint(parm[2], 0, &channel)) { + PR_ERR("c_local:ch is not number\n"); + kfree(buf_orig); + return 0; + } + if (kstrtouint(parm[3], 0, &indx)) { + PR_ERR("c_local:ch is not number\n"); + kfree(buf_orig); + return 0; + } + di_pr_info("c_local:ch[%d],index[%d]\n", channel, indx); + + ppre = get_pre_stru(channel); + ppost = get_post_stru(channel); + #if 0 + if (indx >= ppost->di_post_num) { + PR_ERR("c_local:index is overflow:%d[%d]\n", + indx, ppost->di_post_num); + kfree(buf_orig); + return 0; + } + #endif + pbuf_local = get_buf_local(channel); + di_buf = &pbuf_local[indx]; + } else if (strcmp(parm[0], "capture_pready") == 0) { /*ary add*/ + + if (!di_que_is_empty(channel, QUE_POST_READY)) { + di_buf = di_que_peek(channel, QUE_POST_READY); + pr_info("get post ready di_buf:%d:0x%p\n", + di_buf->index, di_buf); + } else { + pr_info("war:no post ready buf\n"); + } + } else if (strcmp(parm[0], "capture_post") == 0) { + if (di_vf_l_peek(channel)) { + post_vf = di_vf_l_get(channel); + if (!IS_ERR_OR_NULL(post_vf)) { + di_buf = post_vf->private_data; + di_vf_l_put(post_vf, channel); + pr_info("get post di_buf:%d:0x%p\n", + di_buf->index, di_buf); + } else { + pr_info("war:peek no post buf, vfm[0x%p]\n", + post_vf); + } + + post_vf = NULL; + } else { + pr_info("war:can't peek post buf\n"); + } + } else if (strcmp(parm[0], "capture_nrds") == 0) { + dim_get_nr_ds_buf(&dump_adr, &nr_size); + } else { + PR_ERR("wrong dump cmd\n"); + kfree(buf_orig); + return len; + } + if (nr_size == 0) { + if (unlikely(!di_buf)) { + pr_info("war:di_buf is null\n"); + kfree(buf_orig); + return len; + } + canvas_w = di_buf->canvas_width[NR_CANVAS]; + canvas_h = di_buf->canvas_height; + nr_size = canvas_w * canvas_h * 2; + dump_adr = di_buf->nr_adr; + + pr_info("w=%d,h=%d,size=%ld,addr=%lu\n", + canvas_w, canvas_h, nr_size, dump_adr); + } + 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]); + kfree(buf_orig); + return len; + } + dump_state_flag = 1; + if (de_devp->flags & DI_MAP_FLAG) { + /*buff = (void *)phys_to_virt(dump_adr);*/ + buff = dim_vmap(dump_adr, nr_size, &bflg_vmap); + if (!buff) { + if (nr_size <= 5222400) { + pr_info("di_vap err\n"); + filp_close(filp, NULL); + kfree(buf_orig); + return len; + + /*try again:*/ + PR_INF("vap err,size to 5222400, try again\n"); + nr_size = 5222400; + buff = dim_vmap(dump_adr, nr_size, &bflg_vmap); + if (!buff) { + filp_close(filp, NULL); + kfree(buf_orig); + return len; + } + } + } + } else { + buff = ioremap(dump_adr, nr_size); + } + if (IS_ERR_OR_NULL(buff)) + 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); + pr_info("write buffer 0x%lx to %s.\n", dump_adr, parm[1]); + if (bflg_vmap) + dim_unmap_phyaddr(buff); + + if (!(de_devp->flags & DI_MAP_FLAG)) + iounmap(buff); + dump_state_flag = 0; + filp_close(filp, NULL); + set_fs(old_fs); + kfree(buf_orig); + return len; +} + +static void recycle_vframe_type_pre(struct di_buf_s *di_buf, + unsigned int channel); +static void recycle_vframe_type_post(struct di_buf_s *di_buf, + unsigned int channel); +static void add_dummy_vframe_type_pre(struct di_buf_s *src_buf, + unsigned int channel); +#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, irq_flag2 = 0; + unsigned int channel = get_current_channel();/* debug only*/ + struct vframe_s **pvframe_in = get_vframe_in(channel); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + set_init_flag(channel, false);/*init_flag = 0;*/ + di_lock_irqfiq_save(irq_flag2); +/* vf_unreg_provider(&di_vf_prov); */ + pw_vf_light_unreg_provider(channel); + di_unlock_irqfiq_restore(irq_flag2); + set_reg_flag(channel, false); + spin_lock_irqsave(&plist_lock, flags); + di_lock_irqfiq_save(irq_flag2); + if (ppre->di_inp_buf) { + if (pvframe_in[ppre->di_inp_buf->index]) { + pw_vf_put(pvframe_in[ppre->di_inp_buf->index], + channel); + pvframe_in[ppre->di_inp_buf->index] = NULL; + pw_vf_notify_provider(channel, + VFRAME_EVENT_RECEIVER_PUT, NULL); + } + ppre->di_inp_buf->invert_top_bot_flag = 0; + + di_que_in(channel, QUE_IN_FREE, ppre->di_inp_buf); + ppre->di_inp_buf = NULL; + } + dim_uninit_buf(0, channel); + if (get_blackout_policy()) { + dim_DI_Wr(DI_CLKG_CTRL, 0x2); + if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) { + dimh_enable_di_post_mif(GATE_OFF); + dim_post_gate_control(false); + dim_top_gate_control(false, false); + } + } + + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) + dim_set_power_control(0); + + di_unlock_irqfiq_restore(irq_flag2); + spin_unlock_irqrestore(&plist_lock, flags); +} + +ssize_t +store_config(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = 0; + char *parm[2] = { NULL }, *buf_orig; + unsigned int channel = get_current_channel();/* debug only*/ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + buf_orig = kstrdup(buf, GFP_KERNEL); + dim_parse_cmd_params(buf_orig, (char **)(&parm)); + + if (strncmp(buf, "disable", 7) == 0) { + dim_print("%s: disable\n", __func__); + + if (get_init_flag(channel)) {/*if (init_flag) {*/ + ppre->disable_req_flag = 1; + + while (ppre->disable_req_flag) + usleep_range(1000, 1001); + } + } else if (strncmp(buf, "dis2", 4) == 0) { + dis2_di(); + } else if (strcmp(parm[0], "hold_video") == 0) { + pr_info("%s(%s %s)\n", __func__, parm[0], parm[1]); + rc = kstrtouint(parm[1], 10, &hold_video); + } + kfree(buf_orig); + 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, unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + +#define VFRAME_FORMAT_MASK \ + (VIDTYPE_VIU_422 | VIDTYPE_VIU_SINGLE_PLANE | VIDTYPE_VIU_444 | \ + VIDTYPE_MVC) + if ((ppre->cur_width != vframe->width) || + (ppre->cur_height != vframe->height) || + (((ppre->cur_inp_type & VFRAME_FORMAT_MASK) != + (vframe->type & VFRAME_FORMAT_MASK)) && + (!is_handle_prog_frame_as_interlace(vframe))) || + (ppre->cur_source_type != vframe->source_type)) { + /* video format changed */ + return 1; + } else if (((ppre->cur_prog_flag != is_progressive(vframe)) && + (!is_handle_prog_frame_as_interlace(vframe))) || + ((ppre->cur_inp_type & VIDTYPE_VIU_FIELD) != + (vframe->type & VIDTYPE_VIU_FIELD)) + ) { + /* just scan mode changed */ + if (!ppre->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; + +unsigned char dim_is_bypass(vframe_t *vf_in, unsigned int channel) +{ + unsigned int vtype = 0; + int ret = 0; + static vframe_t vf_tmp; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (dimp_get(eDI_MP_di_debug_flag) & 0x10000) /* for debugging */ + return (dimp_get(eDI_MP_di_debug_flag) >> 17) & 0x1; + + if (di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL)) + return 1; + if (ppre->cur_prog_flag && + ((ppre->cur_width > 1920) || + (ppre->cur_height > 1080) || + (ppre->cur_inp_type & VIDTYPE_VIU_444)) + ) + return 1; + + if ((ppre->cur_width < 16) || (ppre->cur_height < 16)) + return 1; + + if (ppre->cur_inp_type & VIDTYPE_MVC) + return 1; + + if (ppre->cur_source_type == VFRAME_SOURCE_TYPE_PPMGR) + return 1; + + if (dimp_get(eDI_MP_bypass_trick_mode)) { + int trick_mode_fffb = 0; + int trick_mode_i = 0; + + if (dimp_get(eDI_MP_bypass_trick_mode) & 0x1) + query_video_status(0, &trick_mode_fffb); + if (dimp_get(eDI_MP_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 (dimp_get(eDI_MP_bypass_3d) && + (ppre->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 0 + if (vf_in && (vf_in->type & VIDTYPE_COMPRESS)) + return 1; +#endif + if ((dimp_get(eDI_MP_di_vscale_skip_enable) & 0x4) && + vf_in && !dimp_get(eDI_MP_post_wr_en)) { + /*--------------------------*/ + if (vf_in->type & VIDTYPE_COMPRESS) { + vf_tmp.width = vf_in->compWidth; + vf_tmp.height = vf_in->compHeight; + if (vf_tmp.width > 1920 || vf_tmp.height > 1088) + return 1; + } + /*--------------------------*/ + /*backup vtype,set type as progressive*/ + vtype = vf_in->type; + vf_in->type &= (~VIDTYPE_TYPEMASK); + vf_in->type &= (~VIDTYPE_VIU_NV21); + vf_in->type |= VIDTYPE_VIU_SINGLE_PLANE; + vf_in->type |= VIDTYPE_VIU_FIELD; + vf_in->type |= VIDTYPE_PRE_INTERLACE; + vf_in->type |= VIDTYPE_VIU_422; + ret = ext_ops.get_current_vscale_skip_count(vf_in); + /*di_vscale_skip_count = (ret&0xff);*/ + dimp_set(eDI_MP_di_vscale_skip_count, ret & 0xff); + /*vpp_3d_mode = ((ret>>8)&0xff);*/ + dimp_set(eDI_MP_vpp_3d_mode, ((ret >> 8) & 0xff)); + vf_in->type = vtype; + if (dimp_get(eDI_MP_di_vscale_skip_count) > 0 || + (dimp_get(eDI_MP_vpp_3d_mode) + #ifdef DET3D + && (!dimp_get(eDI_MP_det3d_en)) + #endif + ) + ) + return 1; + } + + return 0; +} + +static bool need_bypass(struct vframe_s *vf); + +/********************************** + *diff with dim_is_bypass + * delet di_vscale_skip_enable + * use vf_in replace ppre + **********************************/ +bool is_bypass2(struct vframe_s *vf_in, unsigned int ch) +{ + /*check debug info*/ + if (dimp_get(eDI_MP_di_debug_flag) & 0x10000) /* for debugging */ + return true; + + if (di_cfgx_get(ch, eDI_CFGX_BYPASS_ALL)) /*bypass_all*/ + return true; + + if (dimp_get(eDI_MP_bypass_trick_mode)) { + int trick_mode_fffb = 0; + int trick_mode_i = 0; + + if (dimp_get(eDI_MP_bypass_trick_mode) & 0x1) + query_video_status(0, &trick_mode_fffb); + if (dimp_get(eDI_MP_bypass_trick_mode) & 0x2) + query_video_status(1, &trick_mode_i); + trick_mode = trick_mode_fffb | (trick_mode_i << 1); + if (trick_mode) + return true; + } + /* check vframe */ + if (!vf_in) + return false; + + if (need_bypass(vf_in)) + return true; + + if ((vf_in->width < 16) || (vf_in->height < 16)) + return true; + + if (dimp_get(eDI_MP_bypass_3d) && + (vf_in->trans_fmt != 0)) + return true; + +/*prot is conflict with di post*/ + if (vf_in->video_angle) + return true; + + return false; +} + +static unsigned char is_bypass_post(unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (dimp_get(eDI_MP_di_debug_flag) & 0x40000) /* for debugging */ + return (dimp_get(eDI_MP_di_debug_flag) >> 19) & 0x1; + + /*prot is conflict with di post*/ + if (ppre->orientation) + return 1; + if (dimp_get(eDI_MP_bypass_post)) + return 1; + +#ifdef DET3D + if (ppre->vframe_interleave_flag != 0) + return 1; + +#endif + return 0; +} + +#ifdef RUN_DI_PROCESS_IN_IRQ +static unsigned char is_input2pre(void, unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (input2pre && + ppre->cur_prog_flag && + ppre->vdin_source && + (di_bypass_state_get(channel) == 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]; +#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC +static unsigned int di_inp_idx[3]; +#else +static int di_wr_idx; +#endif + +int dim_get_canvas(void) +{ + unsigned int pre_num = 7, post_num = 6; + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (dimp_get(eDI_MP_mcpre_en)) { + /* mem/chan2/nr/mtn/contrd/contrd2/ + * contw/mcinfrd/mcinfow/mcvecw + */ + pre_num = 10; + /* buf0/buf1/buf2/mtnp/mcvec */ + post_num = 6; + } + if (ext_ops.canvas_pool_alloc_canvas_table("di_pre", + &di_pre_idx[0][0], + pre_num, + CANVAS_MAP_TYPE_1)) { + PR_ERR("%s allocate di pre canvas error.\n", __func__); + return 1; + } + if (di_pre_rdma_enable) { + if (ext_ops.canvas_pool_alloc_canvas_table("di_pre", + &di_pre_idx[1][0], + pre_num, + CANVAS_MAP_TYPE_1)) { + PR_ERR("%s allocate di pre canvas error.\n", __func__); + return 1; + } + } else { + #if 0 + for (i = 0; i < pre_num; i++) + di_pre_idx[1][i] = di_pre_idx[0][i]; + #else + memcpy(&di_pre_idx[1][0], + &di_pre_idx[0][0], sizeof(int) * pre_num); + #endif + } + if (ext_ops.canvas_pool_alloc_canvas_table("di_post", + &di_post_idx[0][0], + post_num, + CANVAS_MAP_TYPE_1)) { + PR_ERR("%s allocate di post canvas error.\n", __func__); + return 1; + } + +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + if (ext_ops.canvas_pool_alloc_canvas_table("di_post", + &di_post_idx[1][0], + post_num, + CANVAS_MAP_TYPE_1)) { + PR_ERR("%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]; +#endif +#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + if (ext_ops.canvas_pool_alloc_canvas_table("di_inp", &di_inp_idx[0], 3, + CANVAS_MAP_TYPE_1)) { + PR_ERR("%s allocat di inp canvas error.\n", __func__); + return 1; + } + pr_info("DI: support multi decoding %u~%u~%u.\n", + di_inp_idx[0], di_inp_idx[1], di_inp_idx[2]); +#endif + if (de_devp->post_wr_support == 0) + return 0; + +#ifndef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + if (ext_ops.canvas_pool_alloc_canvas_table("di_wr", + &di_wr_idx, 1, + CANVAS_MAP_TYPE_1)) { + PR_ERR("%s allocat di write back canvas error.\n", + __func__); + return 1; + } + pr_info("DI: support post write back %u.\n", di_wr_idx); +#endif + 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; + } +} + +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); +} + +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_mc, 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 +/********************************************************** + * ./include/linux/amlogic/media/codec_mm/codec_mm.h: + * unsigned long codec_mm_alloc_for_dma(const char *owner, + * int page_cnt, + * int align2n, + * int memflags); + * int codec_mm_free_for_dma(const char *owner, + * unsigned long phy_addr); + * void *codec_mm_phys_to_virt(unsigned long phy_addr); + ***********************************************************/ + +#define TVP_MEM_PAGES 0xffff +/********************************************************** + * alloc mm from codec mm + * o: out: + * return: + * true: seccuss + * false: failed + ***********************************************************/ +static bool mm_codec_alloc(const char *owner, size_t count, + int cma_mode, + struct dim_mm_s *o) +{ + int flags = 0; + bool istvp = false; + + if (codec_mm_video_tvp_enabled()) { + istvp = true; + flags |= CODEC_MM_FLAGS_TVP; + } else { + flags |= CODEC_MM_FLAGS_RESERVED | CODEC_MM_FLAGS_CPU; + } + + if (cma_mode == 4 && !istvp) + flags = CODEC_MM_FLAGS_CMA_FIRST | + CODEC_MM_FLAGS_CPU; + + o->addr = codec_mm_alloc_for_dma(owner, + count, + 0, + flags); + + if (o->addr == 0) { + /*failed*/ + PR_ERR("%s: failed\n", __func__); + return false; + } + + if (istvp) + o->ppage = (struct page *)TVP_MEM_PAGES; + else + o->ppage = codec_mm_phys_to_virt(o->addr); + + /*PR_INF("%s:page:0x%p,add:0x%lx\n", __func__, o->ppage, o->addr);*/ + return true; +} + +/********************************************************** + * ./include/linux/dma-contiguous.h: + * struct page *dma_alloc_from_contiguous(struct device *dev, + * size_t count, + * unsigned int order); + * bool dma_release_from_contiguous(struct device *dev, + * struct page *pages, + * int count); + * + ***********************************************************/ + +/********************************************************** + * alloc mm by cma + * o: out: + * return: + * true: seccuss + * false: failed + ***********************************************************/ +static bool mm_cma_alloc(struct device *dev, size_t count, + struct dim_mm_s *o) +{ + o->ppage = dma_alloc_from_contiguous(dev, count, 0); + if (o->ppage) { + o->addr = page_to_phys(o->ppage); + return true; + } + PR_ERR("%s: failed\n", __func__); + return false; +} + +bool dim_mm_alloc(int cma_mode, size_t count, struct dim_mm_s *o) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + bool ret; + + if (cma_mode == 3 || cma_mode == 4) + ret = mm_codec_alloc(DEVICE_NAME, + count, + cma_mode, + o); + else + ret = mm_cma_alloc(&de_devp->pdev->dev, count, o); + + return ret; +} + +bool dim_mm_release(int cma_mode, + struct page *pages, + int count, + unsigned long addr) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + bool ret = true; + + if (cma_mode == 3 || cma_mode == 4) + codec_mm_free_for_dma(DEVICE_NAME, addr); + else + ret = dma_release_from_contiguous(&de_devp->pdev->dev, + pages, + count); + return ret; +} + +/***********************************************************/ +unsigned int dim_cma_alloc_total(struct di_dev_s *de_devp) +{ + /*struct di_dev_s *de_devp = get_dim_de_devp();*/ + /*****************************************************/ + struct dim_mm_s omm; + bool ret; + + ret = dim_mm_alloc(de_devp->flag_cma, + de_devp->mem_size >> PAGE_SHIFT, &omm); + + if (!ret) /*failed*/ + return 0; + + de_devp->total_pages = omm.ppage; + de_devp->mem_start = omm.addr; + + if (de_devp->flag_cma != 0 && de_devp->nrds_enable) { + dim_nr_ds_buf_init(de_devp->flag_cma, 0, + &de_devp->pdev->dev); + } + + return 1; +} + +static unsigned int di_cma_alloc(struct di_dev_s *devp, unsigned int channel) +{ + unsigned int start_time, end_time, delta_time; + struct di_buf_s *buf_p = NULL; + int itmp, alloc_cnt = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + + unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/ + unsigned int psize; /*new que*/ + struct di_mm_s *mm = dim_mm_get();/*mm-0705*/ + + bool aret; + struct dim_mm_s omm; + + start_time = jiffies_to_msecs(jiffies); + queue_for_each_entry(buf_p, channel, QUEUE_LOCAL_FREE, list) { + if (buf_p->pages) { + PR_ERR("1:%s:buf[%d] page:0x%p alloced skip\n", + __func__, buf_p->index, buf_p->pages); + continue; + } + + aret = dim_mm_alloc(devp->flag_cma, + devp->buffer_size >> PAGE_SHIFT, + &omm); + + if (!aret) { + buf_p->pages = NULL; + PR_ERR("2:%s: alloc failed %d fail.\n", + __func__, buf_p->index); + return 0; + } + + buf_p->pages = omm.ppage; + buf_p->nr_adr = omm.addr; + alloc_cnt++; + mm->sts.num_local++; + if (dimp_get(eDI_MP_cma_print)) + PR_INF("CMA allocate buf[%d]page:0x%p\n", + buf_p->index, buf_p->pages); + + if (dimp_get(eDI_MP_cma_print)) + pr_info(" addr 0x%lx ok.\n", buf_p->nr_adr); + if (ppre->buf_alloc_mode == 0) { + buf_p->mtn_adr = buf_p->nr_adr + + ppre->nr_size; + buf_p->cnt_adr = buf_p->nr_adr + + ppre->nr_size + + ppre->mtn_size; + if (mc_mem_alloc) { + buf_p->mcvec_adr = buf_p->nr_adr + + ppre->nr_size + + ppre->mtn_size + + ppre->count_size; + buf_p->mcinfo_adr = + buf_p->nr_adr + + ppre->nr_size + + ppre->mtn_size + + ppre->count_size + + ppre->mv_size; + } + } + } + PR_INF("%s:num_local[%d]\n", __func__, mm->sts.num_local); + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) { + di_que_list(channel, QUE_POST_FREE, &tmpa[0], &psize); + + for (itmp = 0; itmp < psize; itmp++) { + buf_p = pw_qindex_2_buf(channel, tmpa[itmp]); + + if (buf_p->pages) { + PR_ERR("3:%s:buf[%d] page:0x%p skip\n", + __func__, + buf_p->index, buf_p->pages); + continue; + } + + aret = dim_mm_alloc(devp->flag_cma, + devp->post_buffer_size >> PAGE_SHIFT, + &omm); + + if (!aret) { + buf_p->pages = NULL; + PR_ERR("4:%s: alloc failed %d fail.\n", + __func__, buf_p->index); + return 0; + } + + buf_p->pages = omm.ppage; + buf_p->nr_adr = omm.addr; + mm->sts.num_post++; + alloc_cnt++; + if (dimp_get(eDI_MP_cma_print)) + PR_INF("%s:pbuf[%d]page:0x%p\n", + __func__, + buf_p->index, buf_p->pages); + if (dimp_get(eDI_MP_cma_print)) + pr_info(" addr 0x%lx ok.\n", buf_p->nr_adr); + } + PR_INF("%s:num_pst[%d]\n", __func__, mm->sts.num_post); + } + if (de_devp->flag_cma != 0 && de_devp->nrds_enable) { + dim_nr_ds_buf_init(de_devp->flag_cma, 0, + &de_devp->pdev->dev); + } + + end_time = jiffies_to_msecs(jiffies); + delta_time = end_time - start_time; + pr_info("%s:alloc %u buffer use %u ms(%u~%u)\n", + __func__, alloc_cnt, delta_time, start_time, end_time); + return 1; +} + +static void di_cma_release(struct di_dev_s *devp, unsigned int channel) +{ + unsigned int i, ii, rels_cnt = 0, start_time, end_time, delta_time; + struct di_buf_s *buf_p; + struct di_buf_s *pbuf_local = get_buf_local(channel); + struct di_buf_s *pbuf_post = get_buf_post(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + bool ret; + struct di_mm_s *mm = dim_mm_get(); + + start_time = jiffies_to_msecs(jiffies); + for (i = 0; (i < mm->cfg.num_local); i++) { + buf_p = &pbuf_local[i]; + ii = USED_LOCAL_BUF_MAX; + + if ((ii >= USED_LOCAL_BUF_MAX) && + buf_p->pages) { + ret = dim_mm_release(devp->flag_cma, buf_p->pages, + devp->buffer_size >> PAGE_SHIFT, + buf_p->nr_adr); + if (ret) { + buf_p->pages = NULL; + mm->sts.num_local--; + rels_cnt++; + if (dimp_get(eDI_MP_cma_print)) + pr_info( + "DI release buf[%d] ok.\n", i); + } else { + PR_ERR("%s:release buf[%d] fail.\n", + __func__, i); + } + } else { + if (!IS_ERR_OR_NULL(buf_p->pages) && + dimp_get(eDI_MP_cma_print)) { + pr_info("DI buf[%d] page:0x%p no release.\n", + buf_p->index, buf_p->pages); + } + } + } + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) { + /*mm-0705 for (i = 0; i < ppost->di_post_num; i++) {*/ + for (i = 0; i < mm->cfg.num_post; i++) { + buf_p = &pbuf_post[i]; + if (ppost->keep_buf_post && + i == ppost->keep_buf_post->index) + continue; + + if (!buf_p->pages) { + PR_ERR("2:%s:post buf[%d] is null\n", + __func__, i); + continue; + } + + ret = dim_mm_release(devp->flag_cma, + buf_p->pages, + devp->post_buffer_size >> PAGE_SHIFT, + buf_p->nr_adr); + if (ret) { + buf_p->pages = NULL; + mm->sts.num_post--; + rels_cnt++; + if (dimp_get(eDI_MP_cma_print)) + pr_info( + "DI release post buf[%d] ok.\n", i); + } else { + PR_ERR("%s:release post buf[%d] fail\n", + __func__, i); + } + } + } + if (de_devp->nrds_enable) { + dim_nr_ds_buf_uninit(de_devp->flag_cma, + &de_devp->pdev->dev); + } + if (mm->sts.num_local < 0 || mm->sts.num_post < 0) + PR_ERR("%s:mm:nub_local=%d,nub_post=%d\n", + __func__, + mm->sts.num_local, + mm->sts.num_post); + end_time = jiffies_to_msecs(jiffies); + delta_time = end_time - start_time; + pr_info("%s:release %u buffer use %u ms(%u~%u)\n", + __func__, rels_cnt, delta_time, start_time, end_time); +} +#endif + +bool dim_cma_top_alloc(unsigned int ch) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + bool ret = false; + +#ifdef CONFIG_CMA + + if (di_cma_alloc(de_devp, ch)) + ret = true; +#endif + return ret; +} + +bool dim_cma_top_release(unsigned int ch) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + +#ifdef CONFIG_CMA + di_cma_release(de_devp, ch); + +#endif + return true; +} + +/******************************************* + * + * + ******************************************/ +#define DI_KEEP_BUF_SIZE 3 +static struct di_buf_s *di_keep_buf[DI_KEEP_BUF_SIZE]; +static int di_keep_point; + +void keep_buf_clear(void) +{ + int i; + + for (i = 0; i < DI_KEEP_BUF_SIZE; i++) + di_keep_buf[i] = NULL; + + di_keep_point = -1; +} + +void keep_buf_in(struct di_buf_s *ready_buf) +{ + di_keep_point++; + if (di_keep_point >= DI_KEEP_BUF_SIZE) + di_keep_point = 0; + di_keep_buf[di_keep_point] = ready_buf; +} + +void keep_buf_in_full(struct di_buf_s *ready_buf) +{ + int i; + + keep_buf_in(ready_buf); + for (i = 0; i < DI_KEEP_BUF_SIZE; i++) { + if (!di_keep_buf[i]) + di_keep_buf[i] = ready_buf; + } +} + +int di_cnt_buf(int width, int height, int prog_flag, int mc_mm, + int bit10_support, int pack422) +{ + 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 int nr_canvas_width = width, mtn_canvas_width = width; + unsigned int mv_canvas_width = width, canvas_align_width = 32; + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + canvas_align_width = 64; + + if (dimp_get(eDI_MP_nr10bit_support)) { + if (dimp_get(eDI_MP_full_422_pack)) + nr_width = (width * 5) / 4; + else + nr_width = (width * 3) / 2; + } else { + nr_width = width; + } + /* make sure canvas width must be divided by 256bit|32byte align */ + nr_canvas_width = nr_width << 1; + mtn_canvas_width = mtn_width >> 1; + mv_canvas_width = (mv_width << 1) / 5; + nr_canvas_width = roundup(nr_canvas_width, canvas_align_width); + mtn_canvas_width = roundup(mtn_canvas_width, canvas_align_width); + mv_canvas_width = roundup(mv_canvas_width, canvas_align_width); + nr_width = nr_canvas_width >> 1; + mtn_width = mtn_canvas_width << 1; + mv_width = (mv_canvas_width * 5) >> 1; + + if (prog_flag) { + di_buf_size = nr_width * canvas_height * 2; + di_buf_size = roundup(di_buf_size, PAGE_SIZE); + + } else { + /*pr_info("canvas_height=%d\n", canvas_height);*/ + + /*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;*/ + mc_size = roundup(canvas_height >> 1, canvas_align_width) << 1; + if (mc_mm) { + di_buf_size = nr_size + mtn_size + count_size + + mv_size + mc_size; + } else { + di_buf_size = nr_size + mtn_size + count_size; + } + di_buf_size = roundup(di_buf_size, PAGE_SIZE); + } + + PR_INF("size:0x%x\n", di_buf_size); + PR_INF("\t%-15s:0x%x\n", "nr_size", nr_size); + PR_INF("\t%-15s:0x%x\n", "count", count_size); + PR_INF("\t%-15s:0x%x\n", "mtn", mtn_size); + PR_INF("\t%-15s:0x%x\n", "mv", mv_size); + PR_INF("\t%-15s:0x%x\n", "mcinfo", mc_size); + + di_post_buf_size = nr_width * canvas_height * 2; + /*PR_INF("size:post:0x%x\n", di_post_buf_size);*/ + di_post_buf_size = roundup(di_post_buf_size, PAGE_SIZE); + PR_INF("size:post:0x%x\n", di_post_buf_size); + + return 0; +} + +static int di_init_buf(int width, int height, unsigned char prog_flag, + unsigned int channel) +{ + int i; + int canvas_height = height + 8; + struct page *tmp_page = NULL; + 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 int nr_canvas_width = width, mtn_canvas_width = width; + unsigned int mv_canvas_width = width, canvas_align_width = 32; + unsigned long di_post_mem = 0, nrds_mem = 0; + struct vframe_s **pvframe_in = get_vframe_in(channel); + struct vframe_s *pvframe_in_dup = get_vframe_in_dup(channel); + struct vframe_s *pvframe_local = get_vframe_local(channel); + struct vframe_s *pvframe_post = get_vframe_post(channel); + struct di_buf_s *pbuf_local = get_buf_local(channel); + struct di_buf_s *pbuf_in = get_buf_in(channel); + struct di_buf_s *pbuf_post = get_buf_post(channel); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + struct di_buf_s *keep_buf = ppost->keep_buf; + struct di_dev_s *de_devp = get_dim_de_devp(); + struct di_buf_s *keep_buf_post = ppost->keep_buf_post; + struct di_mm_s *mm = dim_mm_get(); /*mm-0705*/ + + unsigned int mem_st_local; + + /**********************************************/ + /* count buf info */ + /**********************************************/ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + canvas_align_width = 64; + + pr_info("%s:begin\n", __func__); + frame_count = 0; + disp_frame_count = 0; + cur_post_ready_di_buf = NULL; + /* decoder'buffer had been releae no need put */ + for (i = 0; i < MAX_IN_BUF_NUM; i++) + pvframe_in[i] = NULL; + /*pre init*/ + memset(ppre, 0, sizeof(struct di_pre_stru_s)); + + if (dimp_get(eDI_MP_nr10bit_support)) { + if (dimp_get(eDI_MP_full_422_pack)) + nr_width = (width * 5) / 4; + else + nr_width = (width * 3) / 2; + } else { + nr_width = width; + } + /* make sure canvas width must be divided by 256bit|32byte align */ + nr_canvas_width = nr_width << 1; + mtn_canvas_width = mtn_width >> 1; + mv_canvas_width = (mv_width << 1) / 5; + nr_canvas_width = roundup(nr_canvas_width, canvas_align_width); + mtn_canvas_width = roundup(mtn_canvas_width, canvas_align_width); + mv_canvas_width = roundup(mv_canvas_width, canvas_align_width); + nr_width = nr_canvas_width >> 1; + mtn_width = mtn_canvas_width << 1; + mv_width = (mv_canvas_width * 5) >> 1; + + if (prog_flag) { + ppre->prog_proc_type = 1; + ppre->buf_alloc_mode = 1; + di_buf_size = nr_width * canvas_height * 2; + di_buf_size = roundup(di_buf_size, PAGE_SIZE); + } else { + /*pr_info("canvas_height=%d\n", canvas_height);*/ + ppre->prog_proc_type = 0; + ppre->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;*/ + mc_size = roundup(canvas_height >> 1, canvas_align_width) << 1; + if (mc_mem_alloc) { + di_buf_size = nr_size + mtn_size + count_size + + mv_size + mc_size; + } else { + di_buf_size = nr_size + mtn_size + count_size; + } + di_buf_size = roundup(di_buf_size, PAGE_SIZE); + } + de_devp->buffer_size = di_buf_size; + ppre->nr_size = nr_size; + ppre->count_size = count_size; + ppre->mtn_size = mtn_size; + ppre->mv_size = mv_size; + ppre->mcinfo_size = mc_size; + dimp_set(eDI_MP_same_field_top_count, 0); + same_field_bot_count = 0; + dbg_init("size:\n"); + dbg_init("\t%-15s:0x%x\n", "nr_size", ppre->nr_size); + dbg_init("\t%-15s:0x%x\n", "count", ppre->count_size); + dbg_init("\t%-15s:0x%x\n", "mtn", ppre->mtn_size); + dbg_init("\t%-15s:0x%x\n", "mv", ppre->mv_size); + dbg_init("\t%-15s:0x%x\n", "mcinfo", ppre->mcinfo_size); + + /**********************************************/ + /* que init */ + /**********************************************/ + + queue_init(channel, mm->cfg.num_local); + di_que_init(channel); /*new que*/ + + mem_st_local = di_get_mem_start(channel); + + /**********************************************/ + /* local buf init */ + /**********************************************/ + + for (i = 0; i < mm->cfg.num_local; i++) { + struct di_buf_s *di_buf = &pbuf_local[i]; + int ii = USED_LOCAL_BUF_MAX; + + if (!IS_ERR_OR_NULL(keep_buf)) { + for (ii = 0; ii < USED_LOCAL_BUF_MAX; ii++) { + if (di_buf == keep_buf->di_buf_dup_p[ii]) { + dim_print("%s skip %d\n", __func__, i); + break; + } + } + } + + if (ii >= USED_LOCAL_BUF_MAX) { + /* backup cma pages */ + tmp_page = di_buf->pages; + memset(di_buf, 0, sizeof(struct di_buf_s)); + di_buf->pages = tmp_page; + 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_canvas_width; + di_buf->canvas_width[MTN_CANVAS] = mtn_canvas_width; + di_buf->canvas_width[MV_CANVAS] = mv_canvas_width; + if (prog_flag) { + di_buf->canvas_height = canvas_height; + di_buf->canvas_height_mc = canvas_height; + di_buf->nr_adr = mem_st_local + + di_buf_size * i; + di_buf->canvas_config_flag = 1; + } else { + di_buf->canvas_height = (canvas_height >> 1); + di_buf->canvas_height_mc = + roundup(di_buf->canvas_height, + canvas_align_width); + di_buf->nr_adr = mem_st_local + + di_buf_size * i; + di_buf->mtn_adr = mem_st_local + + di_buf_size * i + + nr_size; + di_buf->cnt_adr = mem_st_local + + di_buf_size * i + + nr_size + mtn_size; + + if (mc_mem_alloc) { + di_buf->mcvec_adr = mem_st_local + + di_buf_size * i + + nr_size + mtn_size + + count_size; + di_buf->mcinfo_adr = + mem_st_local + + 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 = &pvframe_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; + di_buf->channel = channel; + queue_in(channel, di_buf, QUEUE_LOCAL_FREE); + dbg_init("buf[%d], addr=0x%lx\n", di_buf->index, + di_buf->nr_adr); + } + } + + if (de_devp->flag_cma == 1 || + de_devp->flag_cma == 4 || + de_devp->flag_cma == 3) { /*trig cma alloc*/ + dip_wq_cma_run(channel, true); + } + + dbg_init("one local buf size:0x%x\n", di_buf_size); + /*mm-0705 di_post_mem = mem_st_local +*/ + /*mm-0705 di_buf_size*de_devp->buf_num_avail;*/ + di_post_mem = mem_st_local + di_buf_size * mm->cfg.num_local; + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) { + di_post_buf_size = nr_width * canvas_height * 2; + #if 0 /*ary test for vout 25Hz*/ + /* pre buffer must 2 more than post buffer */ + if ((de_devp->buf_num_avail - 2) > MAX_POST_BUF_NUM) + ppost->di_post_num = MAX_POST_BUF_NUM; + else + ppost->di_post_num = (de_devp->buf_num_avail - 2); + #else + /*mm-0705 ppost->di_post_num = MAX_POST_BUF_NUM;*/ + #endif + dbg_init("DI: di post buffer size 0x%x byte.\n", + di_post_buf_size); + } else { + /*mm-0705 ppost->di_post_num = MAX_POST_BUF_NUM;*/ + di_post_buf_size = 0; + } + de_devp->post_buffer_size = di_post_buf_size; + + /**********************************************/ + /* input buf init */ + /**********************************************/ + + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + struct di_buf_s *di_buf = &pbuf_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 = &pvframe_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; + di_buf->channel = channel; + di_que_in(channel, QUE_IN_FREE, di_buf); + } + } + /**********************************************/ + /* post buf init */ + /**********************************************/ + /*mm-0705 for (i = 0; i < ppost->di_post_num; i++) {*/ + for (i = 0; i < mm->cfg.num_post; i++) { + struct di_buf_s *di_buf = &pbuf_post[i]; + + if (di_buf) { + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) { + /*ary:for keep buf*/ + if (keep_buf_post && di_buf == keep_buf_post) { + dbg_reg("%s:post keep buf %d:%d\n", + __func__, + i, keep_buf_post->index); + continue; + } + } + + memset(di_buf, 0, sizeof(struct di_buf_s)); + di_buf->type = VFRAME_TYPE_POST; + di_buf->index = i; + di_buf->vframe = &pvframe_post[i]; + di_buf->vframe->private_data = di_buf; + di_buf->queue_index = -1; + di_buf->invert_top_bot_flag = 0; + di_buf->channel = channel; + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) { + 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; + dbg_init("[%d]post buf:%d: addr=0x%lx\n", i, + di_buf->index, di_buf->nr_adr); + } + + di_que_in(channel, QUE_POST_FREE, di_buf); + + } else { + PR_ERR("%s:%d:post buf is null\n", __func__, i); + } + } + if (de_devp->flag_cma == 0 && de_devp->nrds_enable) { + nrds_mem = di_post_mem + mm->cfg.num_post * di_post_buf_size; + /*mm-0705 ppost->di_post_num * di_post_buf_size;*/ + dim_nr_ds_buf_init(de_devp->flag_cma, nrds_mem, + &de_devp->pdev->dev); + } + return 0; +} + +void dim_keep_mirror_buffer(unsigned int channel) /*not use*/ +{ + struct di_buf_s *p = NULL; + int i = 0, ii = 0, itmp; + struct di_post_stru_s *ppost = get_post_stru(channel); + + queue_for_each_entry(p, channel, 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 == ppost->cur_disp_index)) { + ppost->keep_buf = p; + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) { + if (IS_ERR_OR_NULL(p->di_buf_dup_p[i])) + continue; + /* 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(channel, + p->di_buf_dup_p[i], + p->di_buf_dup_p[i]->queue_index + )) + queue_out(channel, p->di_buf_dup_p[i]); + /*which que?*/ + } + ii++; + if (p->di_buf_dup_p[i]->di_wr_linked_buf) + p->di_buf_dup_p[i + 1] = + p->di_buf_dup_p[i]->di_wr_linked_buf; + } + queue_out(channel, p); /*which que?*/ + break; + } + } +} + +void dim_post_keep_mirror_buffer(unsigned int channel) +{ + struct di_buf_s *p = NULL; + int itmp; + bool flg = false; + struct di_post_stru_s *ppost = get_post_stru(channel); + + queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) { + if (p->type != VFRAME_TYPE_POST || + !p->process_fun_index) { + dbg_reg("%s:not post buf:%d\n", + __func__, p->type); + continue; + } + + ppost->keep_buf_post = p; /*only keep one*/ + flg = true; + dbg_reg("%s %d\n", __func__, p->index); + } + + if (flg && ppost->keep_buf_post) { + ppost->keep_buf_post->queue_index = -1; + ppost->keep_buf_post->invert_top_bot_flag = 0; + } +} + +void dim_uninit_buf(unsigned int disable_mirror, unsigned int channel) +{ + /*int i = 0;*/ + struct vframe_s **pvframe_in = get_vframe_in(channel); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (!queue_empty(channel, QUEUE_DISPLAY) || disable_mirror) + ppost->keep_buf = NULL; +#if 0 + if (disable_mirror != 1) + dim_keep_mirror_buffer(); + + if (!IS_ERR_OR_NULL(di_post_stru.keep_buf)) { + keep_buf = di_post_stru.keep_buf; + pr_dbg("%s keep cur di_buf %d (", + __func__, keep_buf->index); + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) { + if (!IS_ERR_OR_NULL(keep_buf->di_buf_dup_p[i])) + pr_dbg("%d\t", + keep_buf->di_buf_dup_p[i]->index); + } + pr_dbg(")\n"); + } +#else + if (!disable_mirror) + dim_post_keep_mirror_buffer(channel); +#endif + queue_init(channel, 0); + di_que_init(channel); /*new que*/ + + /* decoder'buffer had been releae no need put */ + #if 0 + for (i = 0; i < MAX_IN_BUF_NUM; i++) + pvframe_in[i] = NULL; + #else + memset(pvframe_in, 0, sizeof(*pvframe_in) * MAX_IN_BUF_NUM); + #endif + ppre->pre_de_process_flag = 0; + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) { + ppost->cur_post_buf = NULL; + ppost->post_de_busy = 0; + ppost->de_post_process_done = 0; + ppost->post_wr_cnt = 0; + } + if (de_devp->flag_cma == 0 && de_devp->nrds_enable) { + dim_nr_ds_buf_uninit(de_devp->flag_cma, + &de_devp->pdev->dev); + } +} + +void dim_log_buffer_state(unsigned char *tag, unsigned int channel) +{ + struct di_pre_stru_s *ppre; + unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/ + unsigned int psize; /*new que*/ + + if (dimp_get(eDI_MP_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 irq_flag2 = 0; + + ppre = get_pre_stru(channel); + + di_lock_irqfiq_save(irq_flag2); + in_free = di_que_list_count(channel, QUE_IN_FREE); + local_free = list_count(channel, QUEUE_LOCAL_FREE); + pre_ready = di_que_list_count(channel, QUE_PRE_READY); + post_free = di_que_list_count(channel, QUE_POST_FREE); + post_ready = di_que_list_count(channel, QUE_POST_READY); + + di_que_list(channel, QUE_POST_READY, &tmpa[0], &psize); + /*di_que_for_each(channel, p, psize, &tmpa[0]) {*/ + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, tmpa[itmp]); + if (p->di_buf[0]) + post_ready_ext++; + + if (p->di_buf[1]) + post_ready_ext++; + } + queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) { + display++; + if (p->di_buf[0]) + display_ext++; + + if (p->di_buf[1]) + display_ext++; + } + recycle = list_count(channel, QUEUE_RECYCLE); + + if (ppre->di_inp_buf) + di_inp++; + if (ppre->di_wr_buf) + di_wr++; + + if (dimp_get(eDI_MP_buf_state_log_threshold) == 0) + buf_state_log_start = 0; + else if (post_ready < dimp_get(eDI_MP_buf_state_log_threshold)) + buf_state_log_start = 1; + + if (buf_state_log_start) { + dim_print( + "[%s]i i_f %d/%d, l_f %d, pre_r %d, post_f %d/%d,", + tag, + in_free, MAX_IN_BUF_NUM, + local_free, + pre_ready, + post_free, MAX_POST_BUF_NUM); + dim_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); + } +} + +static void dump_state(unsigned int channel) +{ + struct di_buf_s *p = NULL, *keep_buf; + int itmp, i; + struct vframe_s **pvframe_in = get_vframe_in(channel); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/ + unsigned int psize; /*new que*/ + struct di_mm_s *mm = dim_mm_get(); /*mm-0705*/ + + dump_state_flag = 1; + pr_info("version %s, init_flag %d, is_bypass %d\n", + version_s, get_init_flag(channel), + dim_is_bypass(NULL, channel)); + 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=%s, cma_flag=%d\n", + /*atomic_read(&de_devp->mem_flag)*/ + de_devp->buffer_size, di_cma_dbg_get_st_name(channel), + de_devp->flag_cma); + keep_buf = ppost->keep_buf; + pr_info("used_post_buf_index %d(0x%p),", + IS_ERR_OR_NULL(keep_buf) ? + -1 : keep_buf->index, keep_buf); +#if 0 + if (!IS_ERR_OR_NULL(keep_buf)) { + pr_info("used_local_buf_index:\n"); + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) { + p = keep_buf->di_buf_dup_p[i]; + pr_info("%d(0x%p) ", + IS_ERR_OR_NULL(p) ? -1 : p->index, p); + } + } +#endif + pr_info("\nin_free_list (max %d):\n", MAX_IN_BUF_NUM); + + di_que_list(channel, QUE_IN_FREE, &tmpa[0], &psize); + + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, tmpa[itmp]); + pr_info("index %2d, 0x%p, type %d\n", + p->index, p, p->type); + } + pr_info("local_free_list (max %d):\n", mm->cfg.num_local); + queue_for_each_entry(p, channel, 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, channel, QUEUE_POST_DOING, list) { + dim_print_di_buf(p, 2); + } + pr_info("pre_ready_list:\n"); + + di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); + + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, tmpa[itmp]); + dim_print_di_buf(p, 2); + } + pr_info("post_free_list (max %d):\n", mm->cfg.num_post); + + di_que_list(channel, QUE_POST_FREE, &tmpa[0], &psize); + + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, tmpa[itmp]); + + 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"); + + di_que_list(channel, QUE_POST_READY, &tmpa[0], &psize); + + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, tmpa[itmp]); + + dim_print_di_buf(p, 2); + dim_print_di_buf(p->di_buf[0], 1); + dim_print_di_buf(p->di_buf[1], 1); + } + pr_info("display_list:\n"); + queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) { + dim_print_di_buf(p, 2); + dim_print_di_buf(p->di_buf[0], 1); + dim_print_di_buf(p->di_buf[1], 1); + } + pr_info("recycle_list:\n"); + queue_for_each_entry(p, channel, 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 (ppre->di_inp_buf) { + pr_info("di_inp_buf:index %d, 0x%p, type %d\n", + ppre->di_inp_buf->index, + ppre->di_inp_buf, + ppre->di_inp_buf->type); + } else { + pr_info("di_inp_buf: NULL\n"); + } + if (ppre->di_wr_buf) { + pr_info("di_wr_buf:index %d, 0x%p, type %d\n", + ppre->di_wr_buf->index, + ppre->di_wr_buf, + ppre->di_wr_buf->type); + } else { + pr_info("di_wr_buf: NULL\n"); + } + dim_dump_pre_stru(ppre); + dim_dump_post_stru(ppost); + pr_info("vframe_in[]:"); + + for (i = 0; i < MAX_IN_BUF_NUM; i++) + pr_info("0x%p ", pvframe_in[i]); + + pr_info("\n"); + pr_info("vf_peek()=>0x%p, video_peek_cnt = %d\n", + pw_vf_peek(channel), di_sum_get(channel, eDI_SUM_O_PEEK_CNT)); + pr_info("reg_unreg_timerout = %lu\n", reg_unreg_timeout_cnt); + dump_state_flag = 0; +} + +unsigned char dim_check_di_buf(struct di_buf_s *di_buf, int reason, + unsigned int channel) +{ + int error = 0; + struct vframe_s *pvframe_in_dup = get_vframe_in_dup(channel); + struct vframe_s *pvframe_local = get_vframe_local(channel); + struct vframe_s *pvframe_post = get_vframe_post(channel); + + if (!di_buf) { + PR_ERR("%s: %d, di_buf is NULL\n", __func__, reason); + return 1; + } + + if (di_buf->type == VFRAME_TYPE_IN) { + if (di_buf->vframe != &pvframe_in_dup[di_buf->index]) + error = 1; + } else if (di_buf->type == VFRAME_TYPE_LOCAL) { + if (di_buf->vframe != &pvframe_local[di_buf->index]) + error = 1; + } else if (di_buf->type == VFRAME_TYPE_POST) { + if (di_buf->vframe != &pvframe_post[di_buf->index]) + error = 1; + } else { + error = 1; + } + + if (error) { + PR_ERR("%s: %d, di_buf wrong\n", __func__, reason); + if (recovery_flag == 0) + recovery_log_reason = reason; + recovery_flag++; + dim_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 + 2) / 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) +{ + unsigned int pre_size_w = 0, pre_size_h = 0; + + if (di_buf) { + pre_size_w = di_buf->vframe->width; + pre_size_h = (di_buf->vframe->height + 1) / 2; + di_mcinfo_mif->size_x = (pre_size_h + 1) / 2 - 1; + di_mcinfo_mif->size_y = 1; + di_mcinfo_mif->canvas_num = di_buf->mcinfo_canvas_idx; + + di_mcvec_mif->size_x = (pre_size_w + 4) / 5 - 1; + di_mcvec_mif->size_y = pre_size_h - 1; + di_mcvec_mif->canvas_num = di_buf->mcvec_canvas_idx; + } +} + +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; + } +} + +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, unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + vframe_t *vf = di_buf->vframe; + + di_nrwr_mif->canvas_num = di_buf->nr_canvas_idx; + di_nrwr_mif->start_x = 0; + di_nrwr_mif->end_x = vf->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 (ppre->prog_proc_type == 0) + di_nrwr_mif->end_y = vf->height / 2 - 1; + else + di_nrwr_mif->end_y = vf->height - 1; + if (ppre->prog_proc_type == 0) { + di_mtnwr_mif->start_x = 0; + di_mtnwr_mif->end_x = vf->width - 1; + di_mtnwr_mif->start_y = 0; + di_mtnwr_mif->end_y = vf->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, + unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (!di_buf) + 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; + + di_mif->nocompress = (di_buf->vframe->type & VIDTYPE_COMPRESS) ? 0 : 1; + + 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)) || + (ppre->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 (ppre->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) && + (ppre->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 { + /*move to mp di_mif->src_prog = force_prog?1:0;*/ + if (ppre->cur_inp_type & VIDTYPE_INTERLACE) + di_mif->src_prog = 0; + else + di_mif->src_prog + = dimp_get(eDI_MP_force_prog) ? 1 : 0; + 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 di_pre_size_change(unsigned short width, + unsigned short height, + unsigned short vf_type, + unsigned int channel); + +#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC +static void pre_inp_canvas_config(struct vframe_s *vf); +#endif +void dim_pre_de_process(unsigned int channel) +{ + ulong irq_flag2 = 0; + unsigned short pre_width = 0, pre_height = 0; + unsigned char chan2_field_num = 1; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + int canvases_idex = ppre->field_count_for_cont % 2; + unsigned short cur_inp_field_type = VIDTYPE_TYPEMASK; + unsigned short int_mask = 0x7f; + struct di_dev_s *de_devp = get_dim_de_devp(); + + ppre->pre_de_process_flag = 1; + dim_ddbg_mod_save(eDI_DBG_MOD_PRE_SETB, channel, ppre->in_seq);/*dbg*/ + + #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + pre_inp_canvas_config(ppre->di_inp_buf->vframe); + #endif + + config_di_mif(&ppre->di_inp_mif, ppre->di_inp_buf, channel); + /* 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 (ppre->di_mem_buf_dup_p && + ppre->di_mem_buf_dup_p != ppre->di_inp_buf) { + config_canvas_idx(ppre->di_mem_buf_dup_p, + di_pre_idx[canvases_idex][0], -1); + config_cnt_canvas_idx(ppre->di_mem_buf_dup_p, + di_pre_idx[canvases_idex][1]); + } else { + config_cnt_canvas_idx(ppre->di_wr_buf, + di_pre_idx[canvases_idex][1]); + config_di_cnt_mif(&ppre->di_contp2rd_mif, + ppre->di_wr_buf); + } + if (ppre->di_chan2_buf_dup_p) { + config_canvas_idx(ppre->di_chan2_buf_dup_p, + di_pre_idx[canvases_idex][2], -1); + config_cnt_canvas_idx(ppre->di_chan2_buf_dup_p, + di_pre_idx[canvases_idex][3]); + } else { + config_cnt_canvas_idx(ppre->di_wr_buf, + di_pre_idx[canvases_idex][3]); + } + config_canvas_idx(ppre->di_wr_buf, + di_pre_idx[canvases_idex][4], + di_pre_idx[canvases_idex][5]); + config_cnt_canvas_idx(ppre->di_wr_buf, + di_pre_idx[canvases_idex][6]); + if (dimp_get(eDI_MP_mcpre_en)) { + if (ppre->di_chan2_buf_dup_p) + config_mcinfo_canvas_idx(ppre->di_chan2_buf_dup_p, + di_pre_idx[canvases_idex][7]); + else + config_mcinfo_canvas_idx(ppre->di_wr_buf, + di_pre_idx[canvases_idex][7]); + + config_mcinfo_canvas_idx(ppre->di_wr_buf, + di_pre_idx[canvases_idex][8]); + config_mcvec_canvas_idx(ppre->di_wr_buf, + di_pre_idx[canvases_idex][9]); + } +#endif + config_di_mif(&ppre->di_mem_mif, ppre->di_mem_buf_dup_p, channel); + if (!ppre->di_chan2_buf_dup_p) { + config_di_mif(&ppre->di_chan2_mif, + ppre->di_inp_buf, channel); + } else + config_di_mif(&ppre->di_chan2_mif, + ppre->di_chan2_buf_dup_p, channel); + config_di_wr_mif(&ppre->di_nrwr_mif, &ppre->di_mtnwr_mif, + ppre->di_wr_buf, channel); + + if (ppre->di_chan2_buf_dup_p) + config_di_cnt_mif(&ppre->di_contprd_mif, + ppre->di_chan2_buf_dup_p); + else + config_di_cnt_mif(&ppre->di_contprd_mif, + ppre->di_wr_buf); + + config_di_cnt_mif(&ppre->di_contwr_mif, ppre->di_wr_buf); + if (dimp_get(eDI_MP_mcpre_en)) { + if (ppre->di_chan2_buf_dup_p) + config_di_mcinford_mif(&ppre->di_mcinford_mif, + ppre->di_chan2_buf_dup_p); + else + config_di_mcinford_mif(&ppre->di_mcinford_mif, + ppre->di_wr_buf); + + config_di_pre_mc_mif(&ppre->di_mcinfowr_mif, + &ppre->di_mcvecwr_mif, ppre->di_wr_buf); + } + + if ((ppre->di_chan2_buf_dup_p) && + ((ppre->di_chan2_buf_dup_p->vframe->type & VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP)) + chan2_field_num = 0; + + pre_width = ppre->di_nrwr_mif.end_x + 1; + pre_height = ppre->di_nrwr_mif.end_y + 1; + if (ppre->input_size_change_flag) { + cur_inp_field_type = + (ppre->di_inp_buf->vframe->type & VIDTYPE_TYPEMASK); + cur_inp_field_type = + ppre->cur_prog_flag ? VIDTYPE_PROGRESSIVE : cur_inp_field_type; + /*di_async_reset2();*/ + di_pre_size_change(pre_width, pre_height, + cur_inp_field_type, channel); + ppre->input_size_change_flag = false; + } + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (de_devp->nrds_enable) { + dim_nr_ds_mif_config(); + dim_nr_ds_hw_ctrl(true); + int_mask = 0x3f; + } else { + dim_nr_ds_hw_ctrl(false); + } + } + + /* set interrupt mask for pre module. + * we need to only leave one mask open + * to prevent multiple entry for dim_irq + */ + + /*dim_dbg_pre_cnt(channel, "s2");*/ + + dimh_enable_di_pre_aml(&ppre->di_inp_mif, + &ppre->di_mem_mif, + &ppre->di_chan2_mif, + &ppre->di_nrwr_mif, + &ppre->di_mtnwr_mif, + &ppre->di_contp2rd_mif, + &ppre->di_contprd_mif, + &ppre->di_contwr_mif, + ppre->madi_enable, + chan2_field_num, + ppre->vdin2nr); + + dimh_enable_afbc_input(ppre->di_inp_buf->vframe); + + if (dimp_get(eDI_MP_mcpre_en)) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dimh_enable_mc_di_pre_g12(&ppre->di_mcinford_mif, + &ppre->di_mcinfowr_mif, + &ppre->di_mcvecwr_mif, + ppre->mcdi_enable); + else + dimh_enable_mc_di_pre(&ppre->di_mcinford_mif, + &ppre->di_mcinfowr_mif, + &ppre->di_mcvecwr_mif, + ppre->mcdi_enable); + } + + ppre->field_count_for_cont++; + dimh_txl_patch_prog(ppre->cur_prog_flag, + ppre->field_count_for_cont, + dimp_get(eDI_MP_mcpre_en)); + +#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 + /* must make sure follow part issue without interrupts, + * otherwise may cause watch dog reboot + */ + di_lock_irqfiq_save(irq_flag2); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dim_pre_frame_reset_g12(ppre->madi_enable, + ppre->mcdi_enable); + else + dim_pre_frame_reset(); + + /* enable mc pre mif*/ + dimh_enable_di_pre_mif(true, dimp_get(eDI_MP_mcpre_en)); + /*dbg_set_DI_PRE_CTRL();*/ + di_pre_wait_irq_set(true); + di_unlock_irqfiq_restore(irq_flag2); + /*reinit pre busy flag*/ + ppre->pre_de_busy = 1; + + #ifdef SUPPORT_MPEG_TO_VDIN + if (mpeg2vdin_flag) + dim_RDMA_WR_BITS(DI_PRE_CTRL, 1, 13, 1); + #endif + dim_dbg_pre_cnt(channel, "s3"); + ppre->irq_time[0] = cur_to_msecs(); + ppre->irq_time[1] = cur_to_msecs(); + dim_ddbg_mod_save(eDI_DBG_MOD_PRE_SETE, channel, ppre->in_seq);/*dbg*/ + dim_tr_ops.pre_set(ppre->di_wr_buf->vframe->omx_index); +#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 + ppre->pre_de_process_flag = 0; +} + +void dim_pre_de_done_buf_clear(unsigned int channel) +{ + struct di_buf_s *wr_buf = NULL; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (ppre->di_wr_buf) { + wr_buf = ppre->di_wr_buf; + if ((ppre->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(channel, 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(channel, wr_buf, QUEUE_RECYCLE); + ppre->di_wr_buf = NULL; + } + if (ppre->di_inp_buf) { + if (ppre->di_mem_buf_dup_p == ppre->di_inp_buf) + ppre->di_mem_buf_dup_p = NULL; + + queue_in(channel, ppre->di_inp_buf, QUEUE_RECYCLE); + ppre->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; + } + } +} + +void dim_pre_de_done_buf_config(unsigned int channel, bool flg_timeout) +{ + ulong irq_flag2 = 0; + int tmp_cur_lev; + struct di_buf_s *post_wr_buf = NULL; + unsigned int glb_frame_mot_num = 0; + unsigned int glb_field_mot_num = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + dim_dbg_pre_cnt(channel, "d1"); + dim_ddbg_mod_save(eDI_DBG_MOD_PRE_DONEB, channel, ppre->in_seq);/*dbg*/ + if (ppre->di_wr_buf) { + dim_tr_ops.pre_ready(ppre->di_wr_buf->vframe->omx_index); + if (ppre->pre_throw_flag > 0) { + ppre->di_wr_buf->throw_flag = 1; + ppre->pre_throw_flag--; + } else { + ppre->di_wr_buf->throw_flag = 0; + } +#ifdef DET3D + if (ppre->di_wr_buf->vframe->trans_fmt == 0 && + ppre->det3d_trans_fmt != 0 && + dimp_get(eDI_MP_det3d_en)) { + ppre->di_wr_buf->vframe->trans_fmt = + ppre->det3d_trans_fmt; + set3d_view(ppre->det3d_trans_fmt, + ppre->di_wr_buf->vframe); + } +#endif + if (!di_pre_rdma_enable) + ppre->di_post_wr_buf = ppre->di_wr_buf; + post_wr_buf = ppre->di_post_wr_buf; + + if (post_wr_buf && !ppre->cur_prog_flag && + !flg_timeout) { + dim_read_pulldown_info(&glb_frame_mot_num, + &glb_field_mot_num); + if (dimp_get(eDI_MP_pulldown_enable)) + /*pulldown_detection*/ + get_ops_pd()->detection(&post_wr_buf->pd_config, + ppre->mtn_status, + overturn, + ppre->di_inp_buf->vframe); + /*if (combing_fix_en)*/ + if (dimp_get(eDI_MP_combing_fix_en)) { + tmp_cur_lev /*cur_lev*/ + = get_ops_mtn()->adaptive_combing_fixing( + ppre->mtn_status, + glb_field_mot_num, + glb_frame_mot_num, + dimp_get(eDI_MP_di_force_bit_mode)); + dimp_set(eDI_MP_cur_lev, tmp_cur_lev); + } + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) + get_ops_nr()->adaptive_cue_adjust( + glb_frame_mot_num, + glb_field_mot_num); + dim_pulldown_info_clear_g12a(); + } + + if (ppre->cur_prog_flag) { + if (ppre->prog_proc_type == 0) { + /* di_mem_buf_dup->vfrme + * is either local vframe, + * or bot field of vframe from in_list + */ + ppre->di_mem_buf_dup_p->pre_ref_count = 0; + ppre->di_mem_buf_dup_p + = ppre->di_chan2_buf_dup_p; + ppre->di_chan2_buf_dup_p + = ppre->di_wr_buf; +#ifdef DI_BUFFER_DEBUG + dim_print("%s:set di_mem to di_chan2,", __func__); + dim_print("%s:set di_chan2 to di_wr_buf\n", __func__); +#endif + } else { + ppre->di_mem_buf_dup_p->pre_ref_count = 0; + /*recycle the progress throw buffer*/ + if (ppre->di_wr_buf->throw_flag) { + ppre->di_wr_buf-> + pre_ref_count = 0; + ppre->di_mem_buf_dup_p = NULL; +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s set throw %s[%d] pre_ref_count to 0.\n", + __func__, + vframe_type_name[ppre->di_wr_buf->type], + ppre->di_wr_buf->index); +#endif + } else { + ppre->di_mem_buf_dup_p + = ppre->di_wr_buf; + } +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: set di_mem_buf_dup_p to di_wr_buf\n", + __func__); +#endif + } + + ppre->di_wr_buf->seq + = ppre->pre_ready_seq++; + ppre->di_wr_buf->post_ref_count = 0; + ppre->di_wr_buf->left_right + = ppre->left_right; + if (ppre->source_change_flag) { + ppre->di_wr_buf->new_format_flag = 1; + ppre->source_change_flag = 0; + } else { + ppre->di_wr_buf->new_format_flag = 0; + } + if (di_bypass_state_get(channel) == 1) { + ppre->di_wr_buf->new_format_flag = 1; + /*bypass_state = 0;*/ + di_bypass_state_set(channel, false); +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s:bypass_state->0, is_bypass() %d\n", + __func__, dim_is_bypass(NULL, channel)); + dim_print( + "trick_mode %d bypass_all %d\n", + trick_mode, di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL)); +#endif + } + if (ppre->di_post_wr_buf) + di_que_in(channel, QUE_PRE_READY, + ppre->di_post_wr_buf); + +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: %s[%d] => pre_ready_list\n", __func__, + vframe_type_name[ppre->di_wr_buf->type], + ppre->di_wr_buf->index); +#endif + if (ppre->di_wr_buf) { + if (di_pre_rdma_enable) + ppre->di_post_wr_buf = + ppre->di_wr_buf; + else + ppre->di_post_wr_buf = NULL; + ppre->di_wr_buf = NULL; + } + } else { + ppre->di_mem_buf_dup_p->pre_ref_count = 0; + ppre->di_mem_buf_dup_p = NULL; + if (ppre->di_chan2_buf_dup_p) { + ppre->di_mem_buf_dup_p = + ppre->di_chan2_buf_dup_p; +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: di_mem_buf_dup_p = di_chan2_buf_dup_p\n", + __func__); +#endif + } + ppre->di_chan2_buf_dup_p = ppre->di_wr_buf; + + if (ppre->source_change_flag) { + /* add dummy buf, will not be displayed */ + add_dummy_vframe_type_pre(post_wr_buf, + channel); + } + ppre->di_wr_buf->seq = ppre->pre_ready_seq++; + ppre->di_wr_buf->left_right = ppre->left_right; + ppre->di_wr_buf->post_ref_count = 0; + + if (ppre->source_change_flag) { + ppre->di_wr_buf->new_format_flag = 1; + ppre->source_change_flag = 0; + } else { + ppre->di_wr_buf->new_format_flag = 0; + } + if (di_bypass_state_get(channel) == 1) { + ppre->di_wr_buf->new_format_flag = 1; + /*bypass_state = 0;*/ + di_bypass_state_set(channel, false); + +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s:bypass_state->0, is_bypass() %d\n", + __func__, dim_is_bypass(NULL, channel)); + dim_print( + "trick_mode %d bypass_all %d\n", + trick_mode, di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL)); +#endif + } + + if (ppre->di_post_wr_buf) + di_que_in(channel, QUE_PRE_READY, + ppre->di_post_wr_buf); + + dim_print("%s: %s[%d] => pre_ready_list\n", __func__, + vframe_type_name[ppre->di_wr_buf->type], + ppre->di_wr_buf->index); + + if (ppre->di_wr_buf) { + if (di_pre_rdma_enable) + ppre->di_post_wr_buf = ppre->di_wr_buf; + else + ppre->di_post_wr_buf = NULL; + + ppre->di_wr_buf = NULL; + } + } + } + if (ppre->di_post_inp_buf && di_pre_rdma_enable) { +#ifdef DI_BUFFER_DEBUG + dim_print("%s: %s[%d] => recycle_list\n", __func__, + vframe_type_name[ppre->di_post_inp_buf->type], + ppre->di_post_inp_buf->index); +#endif + di_lock_irqfiq_save(irq_flag2); + queue_in(channel, ppre->di_post_inp_buf, QUEUE_RECYCLE); + ppre->di_post_inp_buf = NULL; + di_unlock_irqfiq_restore(irq_flag2); + } + if (ppre->di_inp_buf) { + if (!di_pre_rdma_enable) { +#ifdef DI_BUFFER_DEBUG + dim_print("%s: %s[%d] => recycle_list\n", __func__, + vframe_type_name[ppre->di_inp_buf->type], + ppre->di_inp_buf->index); +#endif + di_lock_irqfiq_save(irq_flag2); + queue_in(channel, ppre->di_inp_buf, QUEUE_RECYCLE); + ppre->di_inp_buf = NULL; + di_unlock_irqfiq_restore(irq_flag2); + } else { + ppre->di_post_inp_buf = ppre->di_inp_buf; + ppre->di_inp_buf = NULL; + } + } + dim_ddbg_mod_save(eDI_DBG_MOD_PRE_DONEE, channel, ppre->in_seq);/*dbg*/ + + dim_dbg_pre_cnt(channel, "d2"); +} + +static void recycle_vframe_type_pre(struct di_buf_s *di_buf, + unsigned int channel) +{ + ulong irq_flag2 = 0; + + di_lock_irqfiq_save(irq_flag2); + + queue_in(channel, di_buf, QUEUE_RECYCLE); + + di_unlock_irqfiq_restore(irq_flag2); +} + +/* + * add dummy buffer to pre ready queue + */ +static void add_dummy_vframe_type_pre(struct di_buf_s *src_buf, + unsigned int channel) +{ + struct di_buf_s *di_buf_tmp = NULL; + + if (!queue_empty(channel, QUEUE_LOCAL_FREE)) { + di_buf_tmp = get_di_buf_head(channel, QUEUE_LOCAL_FREE); + if (di_buf_tmp) { + queue_out(channel, 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; + if (!IS_ERR_OR_NULL(src_buf)) + memcpy(di_buf_tmp->vframe, src_buf->vframe, + sizeof(vframe_t)); + + di_que_in(channel, QUE_PRE_READY, di_buf_tmp); + #ifdef DI_BUFFER_DEBUG + dim_print("%s: dummy %s[%d] => pre_ready_list\n", + __func__, + vframe_type_name[di_buf_tmp->type], + di_buf_tmp->index); + #endif + } + } +} + +/* + * it depend on local buffer queue type is 2 + */ +static int peek_free_linked_buf(unsigned int channel) +{ + struct di_buf_s *p = NULL; + int itmp, p_index = -2; + + if (list_count(channel, QUEUE_LOCAL_FREE) < 2) + return -1; + + queue_for_each_entry(p, channel, 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, unsigned int channel) +{ + struct di_buf_s *di_buf = NULL, *di_buf_linked = NULL; + int pool_idx = 0, di_buf_idx = 0; + struct queue_s *pqueue = get_queue(channel); + struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel); + + queue_t *q = &pqueue[QUEUE_LOCAL_FREE]; + + if (list_count(channel, 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 < pbuf_pool[pool_idx].size) { + di_buf = &(pbuf_pool[pool_idx]. + di_buf_ptr[di_buf_idx]); + queue_out(channel, 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 < pbuf_pool[pool_idx].size) { + di_buf_linked = &(pbuf_pool[pool_idx]. + di_buf_ptr[di_buf_idx]); + queue_out(channel, di_buf_linked); + } + } + if (IS_ERR_OR_NULL(di_buf)) + return NULL; + di_buf->di_wr_linked_buf = di_buf_linked; + } + return di_buf; +} + +#ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC +static void pre_inp_canvas_config(struct vframe_s *vf) +{ + if (vf->canvas0Addr == (u32)-1) { + canvas_config_config(di_inp_idx[0], + &vf->canvas0_config[0]); + canvas_config_config(di_inp_idx[1], + &vf->canvas0_config[1]); + vf->canvas0Addr = (di_inp_idx[1] << 8) | (di_inp_idx[0]); + if (vf->plane_num == 2) { + vf->canvas0Addr |= (di_inp_idx[1] << 16); + } else if (vf->plane_num == 3) { + canvas_config_config(di_inp_idx[2], + &vf->canvas0_config[2]); + vf->canvas0Addr |= (di_inp_idx[2] << 16); + } + vf->canvas1Addr = vf->canvas0Addr; + } +} +#endif + +#if 0 +bool di_get_pre_hsc_down_en(void) +{ + return pre_hsc_down_en; +} +#endif +bool dbg_first_frame; /*debug */ +unsigned int dbg_first_cnt_pre; +unsigned int dbg_first_cnt_post; +#define DI_DBG_CNT (2) +void dim_dbg_pre_cnt(unsigned int channel, char *item) +{ + bool flgs = false; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (ppre->field_count_for_cont < DI_DBG_CNT) { + dbg_first_frame("%d:%s:%d\n", channel, item, + ppre->field_count_for_cont); + dbg_first_frame = true; + flgs = true; + dbg_first_cnt_pre = DI_DBG_CNT * 5; + dbg_first_cnt_post = DI_DBG_CNT * 4 + 1; + } else if (ppre->field_count_for_cont == DI_DBG_CNT) {/*don't use >=*/ + dbg_first_frame = false; + dbg_first_cnt_pre = 0; + dbg_first_cnt_post = 0; + } + + if ((dbg_first_frame) && !flgs && dbg_first_cnt_pre) { + dbg_first_frame("%d:n%s:%d\n", channel, item, + ppre->field_count_for_cont); + dbg_first_cnt_pre--; + } +} + +static void dbg_post_cnt(unsigned int ch, char *item) +{ + struct di_post_stru_s *ppost = get_post_stru(ch); + + if (dbg_first_cnt_post) { + dbg_first_frame("%d:%s:%d\n", ch, item, + ppost->frame_cnt); + dbg_first_cnt_post--; + } +} + +#if 0 +/*must been called when dim_pre_de_buf_config return true*/ +void pre_p_asi_set_next(unsigned int ch) +{ + struct di_pre_stru_s *ppre = get_pre_stru(ch); + + ppre->p_asi_next = ppre->di_inp_buf; +} +#endif + +unsigned char pre_p_asi_de_buf_config(unsigned int ch) +{ + struct di_pre_stru_s *ppre = get_pre_stru(ch); + +#if 0 + if (di_blocking || !dip_cma_st_is_ready(ch)) + return 0; + + if (di_que_list_count(ch, QUE_IN_FREE) < 1) + return 0; + + if (queue_empty(ch, QUEUE_LOCAL_FREE)) + return 0; +#endif + ppre->di_inp_buf = ppre->di_inp_buf_next; + ppre->di_inp_buf_next = NULL; + + if (!ppre->di_mem_buf_dup_p) {/* use n */ + ppre->di_mem_buf_dup_p = ppre->di_inp_buf; + } + + return 1; +} + +/*for first frame no need to ready buf*/ +bool dim_bypass_first_frame(unsigned int ch) +{ + struct di_buf_s *di_buf = NULL; + struct di_buf_s *di_buf_post = NULL; + struct vframe_s *vframe; + struct di_pre_stru_s *ppre = get_pre_stru(ch); + struct vframe_s **pvframe_in = get_vframe_in(ch); + ulong irq_flag2 = 0; + + vframe = pw_vf_peek(ch); + + if (!vframe) + return false; + if (di_que_is_empty(ch, QUE_POST_FREE)) + return false; + + vframe = pw_vf_get(ch); + + di_buf = di_que_out_to_di_buf(ch, QUE_IN_FREE); + + if (dim_check_di_buf(di_buf, 10, ch)) + return 0; + + memcpy(di_buf->vframe, vframe, sizeof(struct vframe_s)); + di_buf->vframe->private_data = di_buf; + pvframe_in[di_buf->index] = vframe; + di_buf->seq = ppre->in_seq; + ppre->in_seq++; + + #if 0 + + if (vframe->type & VIDTYPE_COMPRESS) { /*?*/ + vframe->width = vframe->compWidth; + vframe->height = vframe->compHeight; + } + + di_que_in(ch, QUE_PRE_READY, di_buf); + #endif + + di_buf_post = di_que_out_to_di_buf(ch, QUE_POST_FREE); + memcpy(di_buf_post->vframe, vframe, sizeof(struct vframe_s)); + di_buf_post->vframe->private_data = di_buf_post; + di_lock_irqfiq_save(irq_flag2); + + di_que_in(ch, QUE_POST_READY, di_buf_post); + + di_unlock_irqfiq_restore(irq_flag2); + pw_vf_notify_receiver(ch, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + + PR_INF("%s:ok\n", __func__); + return true; +} + +unsigned char dim_pre_de_buf_config(unsigned int channel) +{ + struct di_buf_s *di_buf = NULL; + struct vframe_s *vframe; + int i, di_linked_buf_idx = -1; + unsigned char change_type = 0; + unsigned char change_type2 = 0; + bool bit10_pack_patch = false; + unsigned int width_roundup = 2; + struct vframe_s **pvframe_in = get_vframe_in(channel); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + int cfg_prog_proc = dimp_get(eDI_MP_prog_proc_config); + + if (di_blocking || !dip_cma_st_is_ready(channel)) + return 0; + + if (di_que_list_count(channel, QUE_IN_FREE) < 1) + return 0; + + if ((di_que_list_count(channel, QUE_IN_FREE) < 2 && + (!ppre->di_inp_buf_next)) || + (queue_empty(channel, QUEUE_LOCAL_FREE))) + return 0; + + if (di_que_list_count(channel, QUE_PRE_READY) >= DI_PRE_READY_LIMIT) + return 0; + + if (dim_is_bypass(NULL, channel)) { + /* some provider has problem if receiver + * get all buffers of provider + */ + int in_buf_num = 0; + /*cur_lev = 0;*/ + dimp_set(eDI_MP_cur_lev, 0); + for (i = 0; i < MAX_IN_BUF_NUM; i++) + if (pvframe_in[i]) + in_buf_num++; + if (in_buf_num > BYPASS_GET_MAX_BUF_NUM +#ifdef DET3D + && (ppre->vframe_interleave_flag == 0) +#endif + ) + return 0; + + dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); + } else if (ppre->prog_proc_type == 2) { + di_linked_buf_idx = peek_free_linked_buf(channel); + if (di_linked_buf_idx == -1 && + !IS_ERR_OR_NULL(ppost->keep_buf)) { + recycle_keep_buffer(channel); + pr_info("%s: recycle keep buffer for peek null linked buf\n", + __func__); + return 0; + } + } + if (ppre->di_inp_buf_next) { + ppre->di_inp_buf = ppre->di_inp_buf_next; + ppre->di_inp_buf_next = NULL; +#ifdef DI_BUFFER_DEBUG + dim_print("%s: di_inp_buf_next %s[%d] => di_inp_buf\n", + __func__, + vframe_type_name[ppre->di_inp_buf->type], + ppre->di_inp_buf->index); +#endif + if (!ppre->di_mem_buf_dup_p) {/* use n */ + ppre->di_mem_buf_dup_p = ppre->di_inp_buf; +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: set di_mem_buf_dup_p to be di_inp_buf\n", + __func__); +#endif + } + } else { + /* check if source change */ + vframe = pw_vf_peek(channel); + + if (vframe && is_from_vdin(vframe)) { +#ifdef RUN_DI_PROCESS_IN_IRQ + ppre->vdin2nr = is_input2pre(channel); +#endif + } + + vframe = pw_vf_get(channel); + + if (!vframe) + return 0; + + dim_tr_ops.pre_get(vframe->omx_index); + didbg_vframe_in_copy(channel, vframe); + + if (vframe->type & VIDTYPE_COMPRESS) { + vframe->width = vframe->compWidth; + vframe->height = vframe->compHeight; + } + dim_print("DI:ch[%d] get %dth vf[0x%p] from frontend %u ms.\n", + channel, + ppre->in_seq, vframe, + jiffies_to_msecs(jiffies_64 - + vframe->ready_jiffies64)); + vframe->prog_proc_config + = (cfg_prog_proc & 0x20) >> 5; + + if (vframe->width > 10000 || vframe->height > 10000 || + hold_video || ppre->bad_frame_throw_count > 0) { + if (vframe->width > 10000 || vframe->height > 10000) + ppre->bad_frame_throw_count = 10; + ppre->bad_frame_throw_count--; + pw_vf_put(vframe, channel); + pw_vf_notify_provider( + channel, VFRAME_EVENT_RECEIVER_PUT, NULL); + return 0; + } + bit10_pack_patch = (is_meson_gxtvbb_cpu() || + is_meson_gxl_cpu() || + is_meson_gxm_cpu()); + width_roundup = bit10_pack_patch ? 16 : width_roundup; + if (dimp_get(eDI_MP_di_force_bit_mode) == 10) + dimp_set(eDI_MP_force_width, + roundup(vframe->width, width_roundup)); + else + dimp_set(eDI_MP_force_width, 0); + ppre->source_trans_fmt = vframe->trans_fmt; + ppre->left_right = ppre->left_right ? 0 : 1; + ppre->invert_flag = + (vframe->type & TB_DETECT_MASK) ? true : false; + vframe->type &= ~TB_DETECT_MASK; + + if ((((invert_top_bot & 0x2) != 0) || + ppre->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; + } + } + ppre->width_bk = vframe->width; + if (dimp_get(eDI_MP_force_width)) + vframe->width = dimp_get(eDI_MP_force_width); + if (dimp_get(eDI_MP_force_height)) + vframe->height = dimp_get(eDI_MP_force_height); + + /* backup frame motion info */ + vframe->combing_cur_lev = dimp_get(eDI_MP_cur_lev);/*cur_lev;*/ + + dim_print("%s: vf_get => 0x%p\n", __func__, vframe); + + di_buf = di_que_out_to_di_buf(channel, QUE_IN_FREE); + + if (dim_check_di_buf(di_buf, 10, channel)) + return 0; + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_VFRAME) + dim_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)); + dim_dbg_pre_cnt(channel, "cf1"); + di_buf->width_bk = ppre->width_bk; /*ary.sui 2019-04-23*/ + di_buf->vframe->private_data = di_buf; + pvframe_in[di_buf->index] = vframe; + di_buf->seq = ppre->in_seq; + ppre->in_seq++; + + pre_vinfo_set(channel, vframe); + change_type = is_source_change(vframe, channel); + #if 0 + if (!change_type) + change_type = is_vinfo_change(channel); + #endif + /* source change, when i mix p,force p as i*/ + if (change_type == 1 || (change_type == 2 && + ppre->cur_prog_flag == 1)) { + if (ppre->di_mem_buf_dup_p) { + /*avoid only 2 i field then p field*/ + if ( + (ppre->cur_prog_flag == 0) && + dimp_get(eDI_MP_use_2_interlace_buff)) + ppre->di_mem_buf_dup_p-> + post_proc_flag = -1; + ppre->di_mem_buf_dup_p->pre_ref_count = 0; + ppre->di_mem_buf_dup_p = NULL; + } + if (ppre->di_chan2_buf_dup_p) { + /*avoid only 1 i field then p field*/ + if ( + (ppre->cur_prog_flag == 0) && + dimp_get(eDI_MP_use_2_interlace_buff)) + ppre->di_chan2_buf_dup_p-> + post_proc_flag = -1; + ppre->di_chan2_buf_dup_p->pre_ref_count = + 0; + ppre->di_chan2_buf_dup_p = NULL; + } + #if 0 + /* channel change will occur between atv and dtv, + * that need mirror + */ + if (!IS_ERR_OR_NULL(di_post_stru.keep_buf)) { + if (di_post_stru.keep_buf->vframe + ->source_type != + di_buf->vframe->source_type) { + recycle_keep_buffer(); + pr_info("%s: source type changed recycle buffer!!!\n", + __func__); + } + } + #endif + pr_info( + "%s:ch[%d]:%ums %dth source change: 0x%x/%d/%d/%d=>0x%x/%d/%d/%d\n", + __func__, + channel, + jiffies_to_msecs(jiffies_64), + ppre->in_seq, + ppre->cur_inp_type, + ppre->cur_width, + ppre->cur_height, + ppre->cur_source_type, + di_buf->vframe->type, + di_buf->vframe->width, + di_buf->vframe->height, + di_buf->vframe->source_type); + if (di_buf->type & VIDTYPE_COMPRESS) { + ppre->cur_width = + di_buf->vframe->compWidth; + ppre->cur_height = + di_buf->vframe->compHeight; + } else { + ppre->cur_width = di_buf->vframe->width; + ppre->cur_height = di_buf->vframe->height; + } + ppre->cur_prog_flag = + is_progressive(di_buf->vframe); + if (ppre->cur_prog_flag) { + if ((dimp_get(eDI_MP_use_2_interlace_buff)) && + !(cfg_prog_proc & 0x10)) + ppre->prog_proc_type = 2; + else + ppre->prog_proc_type + = cfg_prog_proc & 0x10; + } else { + ppre->prog_proc_type = 0; + } + ppre->cur_inp_type = di_buf->vframe->type; + ppre->cur_source_type = + di_buf->vframe->source_type; + ppre->cur_sig_fmt = di_buf->vframe->sig_fmt; + ppre->orientation = di_buf->vframe->video_angle; + ppre->source_change_flag = 1; + ppre->input_size_change_flag = true; +#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 = ppre->cur_width; + vdin_arg.v_active = ppre->cur_height; + if (vdin_ops->tvin_vdin_func) + vdin_ops->tvin_vdin_func(0, &vdin_arg); + mpeg2vdin_flag = 1; + } +#endif + ppre->field_count_for_cont = 0; + } else if (ppre->cur_prog_flag == 0) { + /* check if top/bot interleaved */ + if (change_type == 2) + /* source is i interleaves p fields */ + ppre->force_interlace = true; + if ((ppre->cur_inp_type & + VIDTYPE_TYPEMASK) == (di_buf->vframe->type & + VIDTYPE_TYPEMASK)) { + if ((di_buf->vframe->type & + VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_TOP) + same_field_top_count++; + else + same_field_bot_count++; + } + ppre->cur_inp_type = di_buf->vframe->type; + } else { + ppre->cur_inp_type = di_buf->vframe->type; + } + /*--------------------------*/ + if (!change_type) { + change_type2 = is_vinfo_change(channel); + if (change_type2) { + /*ppre->source_change_flag = 1;*/ + ppre->input_size_change_flag = true; + } + } + + /*--------------------------*/ + if (dim_is_bypass(di_buf->vframe, channel) + /*|| is_bypass_i_p()*/ + /*|| ((ppre->pre_ready_seq % 5)== 0)*/ + /*|| (ppre->pre_ready_seq == 10)*/ + ) { + /* bypass progressive */ + di_buf->seq = ppre->pre_ready_seq++; + di_buf->post_ref_count = 0; + /*cur_lev = 0;*/ + dimp_set(eDI_MP_cur_lev, 0); + if (ppre->source_change_flag) { + di_buf->new_format_flag = 1; + ppre->source_change_flag = 0; + } else { + di_buf->new_format_flag = 0; + } + + if (di_bypass_state_get(channel) == 0) { + if (ppre->di_mem_buf_dup_p) { + ppre->di_mem_buf_dup_p->pre_ref_count = 0; + ppre->di_mem_buf_dup_p = NULL; + } + if (ppre->di_chan2_buf_dup_p) { + ppre->di_chan2_buf_dup_p->pre_ref_count = 0; + ppre->di_chan2_buf_dup_p = NULL; + } + + if (ppre->di_wr_buf) { + ppre->di_wr_buf->pre_ref_count = 0; + ppre->di_wr_buf->post_ref_count = 0; + recycle_vframe_type_pre( + ppre->di_wr_buf, channel); +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: %s[%d] => recycle_list\n", + __func__, + vframe_type_name[ppre->di_wr_buf->type], + ppre->di_wr_buf->index); +#endif + ppre->di_wr_buf = NULL; + } + + di_buf->new_format_flag = 1; + di_bypass_state_set(channel, true);/*bypass_state:1;*/ + + dim_print( + "%s:bypass_state = 1, is_bypass() %d\n", + __func__, dim_is_bypass(NULL, channel)); +#ifdef DI_BUFFER_DEBUG + + dim_print( + "trick_mode %d bypass_all %d\n", + trick_mode, + di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL)); +#endif + } + + top_bot_config(di_buf); + + di_que_in(channel, QUE_PRE_READY, di_buf); + /*if previous isn't bypass post_wr_buf not recycled */ + if (ppre->di_post_wr_buf && di_pre_rdma_enable) { + queue_in(channel, ppre->di_post_inp_buf, + QUEUE_RECYCLE); + ppre->di_post_inp_buf = NULL; + } + + if ((bypass_pre & 0x2) && !ppre->cur_prog_flag) + di_buf->post_proc_flag = -2; + else + di_buf->post_proc_flag = 0; + + dim_print("di:cfg:post_proc_flag=%d\n", + di_buf->post_proc_flag); +#ifdef DI_BUFFER_DEBUG + dim_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; + + pvframe_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 = di_que_out_to_di_buf(channel, QUE_IN_FREE); + if (dim_check_di_buf(di_buf_tmp, 10, channel)) { + recycle_vframe_type_pre(di_buf, channel); + 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 = ppre->in_seq; + ppre->in_seq++; + pvframe_in[di_buf_tmp->index] = vframe; + memcpy(di_buf_tmp->vframe, vframe, + sizeof(vframe_t)); + ppre->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; + + ppre->di_inp_buf = di_buf; +#ifdef DI_BUFFER_DEBUG + dim_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 (!ppre->di_mem_buf_dup_p) { + ppre->di_mem_buf_dup_p = di_buf; +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: set di_mem_buf_dup_p to be di_inp_buf\n", + __func__); +#endif + } + } else { + di_buf->post_proc_flag = 0; + if ((cfg_prog_proc & 0x40) || + ppre->force_interlace) + di_buf->post_proc_flag = 1; + + ppre->di_inp_buf = di_buf; +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: %s[%d] => di_inp_buf\n", + __func__, + vframe_type_name[di_buf->type], + di_buf->index); +#endif + if (!ppre->di_mem_buf_dup_p) { + /* use n */ + ppre->di_mem_buf_dup_p = di_buf; +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: set di_mem_buf_dup_p to be di_inp_buf\n", + __func__); +#endif + } + } + } else { + /*********************************/ + if ((di_buf->vframe->width >= 1920) && + (di_buf->vframe->height >= 1080) && + is_meson_tl1_cpu()) { + /*if (combing_fix_en) {*/ + if (dimp_get(eDI_MP_combing_fix_en)) { + /*combing_fix_en = false;*/ + dimp_set(eDI_MP_combing_fix_en, 0); + get_ops_mtn()->fix_tl1_1080i_sawtooth_patch(); + } + } else { + /*combing_fix_en = true;*/ + dimp_set(eDI_MP_combing_fix_en, 1); + } + + /*********************************/ + if (!ppre->di_chan2_buf_dup_p) { + ppre->field_count_for_cont = 0; + /* ignore contp2rd and contprd */ + } + di_buf->post_proc_flag = 1; + ppre->di_inp_buf = di_buf; + dim_print("%s: %s[%d] => di_inp_buf\n", __func__, + vframe_type_name[di_buf->type], + di_buf->index); + + if (!ppre->di_mem_buf_dup_p) {/* use n */ + ppre->di_mem_buf_dup_p = di_buf; +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s: set di_mem_buf_dup_p to be di_inp_buf\n", + __func__); +#endif + } + } + } + /*dim_dbg_pre_cnt(channel, "cfg");*/ + /* di_wr_buf */ + if (ppre->prog_proc_type == 2) { + di_linked_buf_idx = peek_free_linked_buf(channel); + if (di_linked_buf_idx != -1) + di_buf = get_free_linked_buf(di_linked_buf_idx, + channel); + else + di_buf = NULL; + if (!di_buf) { + /* recycle_vframe_type_pre(di_pre_stru.di_inp_buf); + *save for next process + */ + recycle_keep_buffer(channel); + ppre->di_inp_buf_next = ppre->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(channel, QUEUE_LOCAL_FREE); + if (dim_check_di_buf(di_buf, 11, channel)) { + /* recycle_keep_buffer(); + * pr_dbg("%s:recycle keep buffer\n", __func__); + */ + recycle_vframe_type_pre(ppre->di_inp_buf, channel); + return 0; + } + queue_out(channel, di_buf);/*QUEUE_LOCAL_FREE*/ + if (ppre->prog_proc_type & 0x10) + di_buf->canvas_config_flag = 1; + else + di_buf->canvas_config_flag = 2; + di_buf->di_wr_linked_buf = NULL; + } + + ppre->di_wr_buf = di_buf; + ppre->di_wr_buf->pre_ref_count = 1; + +#ifdef DI_BUFFER_DEBUG + dim_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) + dim_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 + if (ppre->cur_inp_type & VIDTYPE_COMPRESS) { + ppre->di_inp_buf->vframe->width = + ppre->di_inp_buf->vframe->compWidth; + ppre->di_inp_buf->vframe->height = + ppre->di_inp_buf->vframe->compHeight; + } + + memcpy(di_buf->vframe, + ppre->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 (de_devp->pps_enable && dimp_get(eDI_MP_pps_position)) { + if (dimp_get(eDI_MP_pps_dstw) != di_buf->vframe->width) { + di_buf->vframe->width = dimp_get(eDI_MP_pps_dstw); + ppre->width_bk = dimp_get(eDI_MP_pps_dstw); + } + if (dimp_get(eDI_MP_pps_dsth) != di_buf->vframe->height) + di_buf->vframe->height = dimp_get(eDI_MP_pps_dsth); + } else if (de_devp->h_sc_down_en) { + if (di_mp_uit_get(eDI_MP_pre_hsc_down_width) + != di_buf->vframe->width) { + pr_info("di: hscd %d to %d\n", di_buf->vframe->width, + di_mp_uit_get(eDI_MP_pre_hsc_down_width)); + di_buf->vframe->width = + di_mp_uit_get(eDI_MP_pre_hsc_down_width); + /*di_pre_stru.width_bk = pre_hsc_down_width;*/ + di_buf->width_bk = + di_mp_uit_get(eDI_MP_pre_hsc_down_width); + } + } + if (dimp_get(eDI_MP_di_force_bit_mode) == 10) { + di_buf->vframe->bitdepth |= (BITDEPTH_Y10); + if (dimp_get(eDI_MP_full_422_pack)) + di_buf->vframe->bitdepth |= (FULL_PACK_422_MODE); + } else { + di_buf->vframe->bitdepth |= (BITDEPTH_Y8); + } + di_buf->width_bk = ppre->width_bk; /*ary:2019-04-23*/ + if (ppre->prog_proc_type) { + di_buf->vframe->type = VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD; + if (ppre->cur_inp_type & VIDTYPE_PRE_INTERLACE) + di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE; + } else { + if ( + ((ppre->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; + /*add for vpp skip line ref*/ + if (di_bypass_state_get(channel) == 0) + di_buf->vframe->type |= VIDTYPE_PRE_INTERLACE; + } + + if (is_bypass_post(channel)) { + if (dimp_get(eDI_MP_bypass_post_state) == 0) + ppre->source_change_flag = 1; + + dimp_set(eDI_MP_bypass_post_state, 1); + } else { + if (dimp_get(eDI_MP_bypass_post_state)) + ppre->source_change_flag = 1; + + dimp_set(eDI_MP_bypass_post_state, 0); + } + + if (ppre->di_inp_buf->post_proc_flag == 0) { + ppre->madi_enable = 0; + ppre->mcdi_enable = 0; + di_buf->post_proc_flag = 0; + dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); + } else if (dimp_get(eDI_MP_bypass_post_state)) { + ppre->madi_enable = 0; + ppre->mcdi_enable = 0; + di_buf->post_proc_flag = 0; + dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); + } else { + ppre->madi_enable = (dimp_get(eDI_MP_pre_enable_mask) & 1); + ppre->mcdi_enable = + ((dimp_get(eDI_MP_pre_enable_mask) >> 1) & 1); + di_buf->post_proc_flag = 1; + dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, + dimp_get(eDI_MP_mcpre_en));/*en*/ + } + if ((ppre->di_mem_buf_dup_p == ppre->di_wr_buf) || + (ppre->di_chan2_buf_dup_p == ppre->di_wr_buf)) { + pr_dbg("+++++++++++++++++++++++\n"); + if (recovery_flag == 0) + recovery_log_reason = 12; + + recovery_flag++; + return 0; + } + return 1; +} + +int dim_check_recycle_buf(unsigned int channel) +{ + struct di_buf_s *di_buf = NULL;/* , *ptmp; */ + int itmp; + int ret = 0; + struct vframe_s **pvframe_in = get_vframe_in(channel); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (di_blocking) + return ret; + queue_for_each_entry(di_buf, channel, QUEUE_RECYCLE, list) { + if ((di_buf->pre_ref_count == 0) && + (di_buf->post_ref_count <= 0)) { /*ary maybe <=*/ + if (di_buf->type == VFRAME_TYPE_IN) { + queue_out(channel, di_buf); + if (pvframe_in[di_buf->index]) { + pw_vf_put( + pvframe_in[di_buf->index], + channel); + pw_vf_notify_provider(channel, + VFRAME_EVENT_RECEIVER_PUT, + NULL); + dim_print( + "%s: ch[%d],vf_put(%d) %x, %u ms\n", + __func__, + channel, + ppre->recycle_seq, + pvframe_in[di_buf->index], + jiffies_to_msecs(jiffies_64 - + pvframe_in[di_buf->index]->ready_jiffies64)); + pvframe_in[di_buf->index] = NULL; + } + di_buf->invert_top_bot_flag = 0; + + di_que_in(channel, QUE_IN_FREE, di_buf); + ppre->recycle_seq++; + ret |= 1; + } else { + queue_out(channel, di_buf); + di_buf->invert_top_bot_flag = 0; + queue_in(channel, di_buf, QUEUE_LOCAL_FREE); + di_buf->post_ref_count = 0;/*ary maybe*/ + if (di_buf->di_wr_linked_buf) { + queue_in(channel, + di_buf->di_wr_linked_buf, + QUEUE_LOCAL_FREE); +#ifdef DI_BUFFER_DEBUG + dim_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 + dim_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(unsigned int channel) +{ + unsigned int data32 = 0, likely_val = 0; + unsigned long frame_sum = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (!dimp_get(eDI_MP_det3d_en)) + return; + + data32 = get_ops_3d()->det3d_fmt_detect();/*det3d_fmt_detect();*/ + switch (data32) { + case TVIN_TFMT_3D_DET_LR: + case TVIN_TFMT_3D_LRH_OLOR: + ppre->det_lr++; + break; + case TVIN_TFMT_3D_DET_TB: + case TVIN_TFMT_3D_TB: + ppre->det_tp++; + break; + case TVIN_TFMT_3D_DET_INTERLACE: + ppre->det_la++; + break; + default: + ppre->det_null++; + break; + } + + if (det3d_mode != data32) { + det3d_mode = data32; + dim_print("[det3d..]new 3d fmt: %d\n", det3d_mode); + } + if (frame_count > 20) { + frame_sum = ppre->det_lr + ppre->det_tp + + ppre->det_la + + ppre->det_null; + if ((frame_count % det3d_frame_cnt) || (frame_sum > UINT_MAX)) + return; + likely_val = max3(ppre->det_lr, + ppre->det_tp, + ppre->det_la); + if (ppre->det_null >= likely_val) + det3d_mode = 0; + else if (likely_val == ppre->det_lr) + det3d_mode = TVIN_TFMT_3D_LRH_OLOR; + else if (likely_val == ppre->det_tp) + det3d_mode = TVIN_TFMT_3D_TB; + else + det3d_mode = TVIN_TFMT_3D_DET_INTERLACE; + ppre->det3d_trans_fmt = det3d_mode; + } else { + ppre->det3d_trans_fmt = 0; + } +} +#endif + +static unsigned int ro_mcdi_col_cfd[26]; +static void get_mcinfo_from_reg_in_irq(unsigned int channel) +{ + unsigned int i = 0, ncolcrefsum = 0, blkcount = 0, *reg = NULL; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + +/*get info for current field process by post*/ + ppre->di_wr_buf->curr_field_mcinfo.highvertfrqflg = + (Rd(MCDI_RO_HIGH_VERT_FRQ_FLG) & 0x1); +/* post:MCDI_MC_REL_GAIN_OFFST_0 */ + ppre->di_wr_buf->curr_field_mcinfo.motionparadoxflg = + (Rd(MCDI_RO_MOTION_PARADOX_FLG) & 0x1); +/* post:MCDI_MC_REL_GAIN_OFFST_0 */ + reg = ppre->di_wr_buf->curr_field_mcinfo.regs; + for (i = 0; i < 26; i++) { + ro_mcdi_col_cfd[i] = Rd(0x2fb0 + i); + ppre->di_wr_buf->curr_field_mcinfo.regs[i] = 0; + if (!dimp_get(eDI_MP_calc_mcinfo_en)) + *(reg + i) = ro_mcdi_col_cfd[i]; + } + if (dimp_get(eDI_MP_calc_mcinfo_en)) { + blkcount = (ppre->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 > dimp_get(eDI_MP_colcfd_thr)) + for (i = 0; i < blkcount; i++) + *(reg + i / 32) += (1 << (i % 32)); + } + } +} + +static unsigned int bit_reverse(unsigned int val) +{ + unsigned int i = 0, res = 0; + + for (i = 0; i < 16; i++) { + res |= (((val & (1 << i)) >> i) << (31 - i)); + res |= (((val & (1 << (31 - i))) << i) >> (31 - i)); + } + return res; +} + +static void set_post_mcinfo(struct mcinfo_pre_s *curr_field_mcinfo) +{ + unsigned int i = 0, value = 0; + + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_REL_GAIN_OFFST_0, + curr_field_mcinfo->highvertfrqflg, 24, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_REL_GAIN_OFFST_0, + curr_field_mcinfo->motionparadoxflg, 25, 1); + for (i = 0; i < 26; i++) { + if (overturn) + value = bit_reverse(curr_field_mcinfo->regs[i]); + else + value = curr_field_mcinfo->regs[i]; + dim_VSYNC_WR_MPEG_REG(0x2f78 + i, value); + } +} + +static unsigned char intr_mode; + +irqreturn_t dim_irq(int irq, void *dev_instance) +{ + unsigned int channel; + struct di_pre_stru_s *ppre; + struct di_dev_s *de_devp = get_dim_de_devp(); + struct di_hpre_s *pre = get_hw_pre(); + +#ifndef CHECK_DI_DONE + unsigned int data32 = Rd(DI_INTR_CTRL); + unsigned int mask32 = (data32 >> 16) & 0x3ff; + unsigned int flag = 0; + + channel = pre->curr_ch; + ppre = pre->pres; + + data32 &= 0x3fffffff; + if ((data32 & 1) == 0 && dimp_get(eDI_MP_di_dbg_mask) & 8) + pr_info("irq[%d]pre|post=0 write done.\n", irq); + if (ppre->pre_de_busy) { + /* only one inetrrupr mask should be enable */ + if ((data32 & 2) && !(mask32 & 2)) { + dim_print("irq pre MTNWR ==ch[%d]\n", channel); + flag = 1; + } else if ((data32 & 1) && !(mask32 & 1)) { + dim_print("irq pre NRWR ==ch[%d]\n", channel); + flag = 1; + } else { + dim_print("irq pre DI IRQ 0x%x ==\n", data32); + flag = 0; + } + } + +#else + channel = pre->curr_ch; + ppre = pre->pres; +#endif + +#ifdef DET3D + if (dimp_get(eDI_MP_det3d_en)) { + if ((data32 & 0x100) && !(mask32 & 0x100) && flag) { + dim_DI_Wr(DI_INTR_CTRL, data32); + det3d_irq(channel); + } else { + goto end; + } + } else { + dim_DI_Wr(DI_INTR_CTRL, data32); + } +#else + if (flag) + dim_DI_Wr(DI_INTR_CTRL, + (data32 & 0xfffffffb) | (intr_mode << 30)); +#endif + + /*if (ppre->pre_de_busy == 0) {*/ + if (!di_pre_wait_irq_get()) { + PR_ERR("%s:ch[%d]:enter:reg[0x%x]= 0x%x,dtab[%d]\n", __func__, + channel, + DI_INTR_CTRL, + Rd(DI_INTR_CTRL), + pre->sdt_mode.op_crr); + return IRQ_HANDLED; + } + + if (flag) { + ppre->irq_time[0] = + (cur_to_msecs() - ppre->irq_time[0]); + + dim_tr_ops.pre(ppre->field_count_for_cont, ppre->irq_time[0]); + + /*add from valsi wang.feng*/ + dim_arb_sw(false); + dim_arb_sw(true); + if (dimp_get(eDI_MP_mcpre_en)) { + get_mcinfo_from_reg_in_irq(channel); + if ((is_meson_gxlx_cpu() && + ppre->field_count_for_cont >= 4) || + is_meson_txhd_cpu()) + dimh_mc_pre_mv_irq(); + dimh_calc_lmv_base_mcinfo((ppre->cur_height >> 1), + ppre->di_wr_buf->mcinfo_adr, + ppre->mcinfo_size); + } + get_ops_nr()->nr_process_in_irq(); + if ((data32 & 0x200) && de_devp->nrds_enable) + dim_nr_ds_irq(); + /* disable mif */ + dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en)); + + ppre->pre_de_busy = 0; + + if (get_init_flag(channel)) + /* pr_dbg("%s:up di sema\n", __func__); */ + task_send_ready(); + + pre->flg_int_done = 1; + } + + return IRQ_HANDLED; +} + +irqreturn_t dim_post_irq(int irq, void *dev_instance) +{ + unsigned int data32 = Rd(DI_INTR_CTRL); + unsigned int channel; + struct di_post_stru_s *ppost; + struct di_hpst_s *pst = get_hw_pst(); + + channel = pst->curr_ch; + ppost = pst->psts; + + data32 &= 0x3fffffff; + if ((data32 & 4) == 0) { + if (dimp_get(eDI_MP_di_dbg_mask) & 8) + pr_info("irq[%d]post write undone.\n", irq); + return IRQ_HANDLED; + } + + if (pst->state != eDI_PST_ST_WAIT_INT) { + PR_ERR("%s:ch[%d]:s[%d]\n", __func__, channel, pst->state); + ddbg_sw(eDI_LOG_TYPE_MOD, false); + return IRQ_HANDLED; + } + dim_ddbg_mod_save(eDI_DBG_MOD_POST_IRQB, pst->curr_ch, + ppost->frame_cnt); + dim_tr_ops.post_ir(0); + + if ((dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) && + (data32 & 0x4)) { + ppost->de_post_process_done = 1; + ppost->post_de_busy = 0; + ppost->irq_time = + (cur_to_msecs() - ppost->irq_time); + + dim_tr_ops.post(ppost->post_wr_cnt, ppost->irq_time); + + dim_DI_Wr(DI_INTR_CTRL, + (data32 & 0xffff0004) | (intr_mode << 30)); + /* disable wr back avoid pps sreay in g12a */ + dim_DI_Wr_reg_bits(DI_POST_CTRL, 0, 7, 1); + di_post_set_flow(1, eDI_POST_FLOW_STEP1_STOP); /*dbg a*/ + dim_print("irq p ch[%d]done\n", channel); + pst->flg_int_done = true; + } + dim_ddbg_mod_save(eDI_DBG_MOD_POST_IRQE, pst->curr_ch, + ppost->frame_cnt); + + if (get_init_flag(channel)) + task_send_ready(); + + return IRQ_HANDLED; +} + +/* + * di post process + */ +static void inc_post_ref_count(struct di_buf_s *di_buf) +{ + int i; /*debug only:*/ + + /* int post_blend_mode; */ + if (IS_ERR_OR_NULL(di_buf)) { + PR_ERR("%s:\n", __func__); + if (recovery_flag == 0) + recovery_log_reason = 13; + + recovery_flag++; + 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_ref_count++; + + if (di_buf->di_buf_dup_p[2]) + di_buf->di_buf_dup_p[2]->post_ref_count++; + + /*debug only:*/ + for (i = 0; i < 3; i++) { + if (di_buf->di_buf_dup_p[i]) + dbg_post_ref("%s:pst_buf[%d],dup_p[%d],pref[%d]\n", + __func__, + di_buf->index, + i, + di_buf->di_buf_dup_p[i]->post_ref_count); + } +} + +static void dec_post_ref_count(struct di_buf_s *di_buf) +{ + int i; /*debug only:*/ + + if (IS_ERR_OR_NULL(di_buf)) { + PR_ERR("%s:\n", __func__); + if (recovery_flag == 0) + recovery_log_reason = 14; + + recovery_flag++; + return; + } + if (di_buf->pd_config.global_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--; + + /*debug only:*/ + for (i = 0; i < 3; i++) { + if (di_buf->di_buf_dup_p[i]) + dbg_post_ref("%s:pst_buf[%d],dup_p[%d],pref[%d]\n", + __func__, + di_buf->index, + i, + di_buf->di_buf_dup_p[i]->post_ref_count); + } +} + +#if 0 /*no use*/ +static void vscale_skip_disable_post(struct di_buf_s *di_buf, + vframe_t *disp_vf, unsigned int channel) +{ + struct di_buf_s *di_buf_i = NULL; + int canvas_height = di_buf->di_buf[0]->canvas_height; + struct di_post_stru_s *ppost = get_post_stru(channel); + + 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[ppost->canvas_id][0]; + disp_vf->canvas1Addr = di_post_idx[ppost->canvas_id][0]; + canvas_config( + di_post_idx[ppost->canvas_id][0], + di_buf_i->nr_adr, di_buf_i->canvas_width[NR_CANVAS], + canvas_height, 0, 0); + dimh_disable_post_deinterlace_2(); + ppost->vscale_skip_flag = true; +} +#endif + +/*early_process_fun*/ +static int early_NONE(void) +{ + return 0; +} + +int dim_do_post_wr_fun(void *arg, vframe_t *disp_vf) +{ + #if 0 + struct di_post_stru_s *ppost; + int i; + + for (i = 0; i < DI_CHANNEL_NUB; i++) { + ppost = get_post_stru(i); + + ppost->toggle_flag = true; + } + return 1; + #else + return early_NONE(); + #endif +} + +static int de_post_disable_fun(void *arg, vframe_t *disp_vf) +{ + #if 0 + struct di_buf_s *di_buf = (struct di_buf_s *)arg; + unsigned int channel = di_buf->channel; + struct di_post_stru_s *ppost = get_post_stru(channel); + + ppost->vscale_skip_flag = false; + ppost->toggle_flag = true; + + PR_ERR("%s------------------------------\n", __func__); + + process_vscale_skip(di_buf, disp_vf, channel); +/* for atv static image flickering */ + if (di_buf->process_fun_index == PROCESS_FUN_NULL) + dimh_disable_post_deinterlace_2(); + + return 1; +/* called for new_format_flag, make + * video set video_property_changed + */ + #else + return early_NONE(); + #endif +} + +static int do_nothing_fun(void *arg, vframe_t *disp_vf) +{ + #if 0 + struct di_buf_s *di_buf = (struct di_buf_s *)arg; + unsigned int channel = di_buf->channel; + struct di_post_stru_s *ppost = get_post_stru(channel); + + ppost->vscale_skip_flag = false; + ppost->toggle_flag = true; + + PR_ERR("%s------------------------------\n", __func__); + + process_vscale_skip(di_buf, disp_vf, channel); + + if (di_buf->process_fun_index == PROCESS_FUN_NULL) { + if (Rd(DI_IF1_GEN_REG) & 0x1 || Rd(DI_POST_CTRL) & 0xf) + dimh_disable_post_deinterlace_2(); + /*if(di_buf->pulldown_mode == PULL_DOWN_EI && Rd(DI_IF1_GEN_REG)&0x1) + * dim_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, 0x3 << 30); + */ + } + return 0; + #else + return early_NONE(); + #endif +} + +static int do_pre_only_fun(void *arg, vframe_t *disp_vf) +{ + #if 0 + unsigned int channel; + struct di_post_stru_s *ppost; + + PR_ERR("%s------------------------------\n", __func__); +#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; + + channel = di_buf->channel; + ppost = get_post_stru(channel); + + ppost->vscale_skip_flag = false; + ppost->toggle_flag = true; + + if (!vf || !di_buf->di_buf[0]) { + dim_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()) { + ppost->canvas_id = ppost->next_canvas_id; + } else { + ppost->canvas_id = 0; + ppost->next_canvas_id = 1; + if (post_wr_en && post_wr_support) + ppost->canvas_id = ppost->next_canvas_id; + } +#endif + + canvas_config( + di_post_idx[ppost->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[ppost->canvas_id][0]; + vf->canvas1Addr = + di_post_idx[ppost->canvas_id][0]; +#ifdef DET3D + if (ppre->vframe_interleave_flag && di_buf->di_buf[1]) { + canvas_config( + di_post_idx[ppost->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[ppost->canvas_id][1]; + vf->duration <<= 1; + } +#endif + ppost->next_canvas_id = ppost->canvas_id ? 0 : 1; + + if (di_buf->process_fun_index == PROCESS_FUN_NULL) { + if (Rd(DI_IF1_GEN_REG) & 0x1 || + Rd(DI_POST_CTRL) & 0x10f) + dimh_disable_post_deinterlace_2(); + } + } +#endif + + return 0; +#else + return early_NONE(); +#endif +} + +static void get_vscale_skip_count(unsigned int par) +{ + /*di_vscale_skip_count_real = (par >> 24) & 0xff;*/ + dimp_set(eDI_MP_di_vscale_skip_count_real, + (par >> 24) & 0xff); +} + +#define get_vpp_reg_update_flag(par) (((par) >> 16) & 0x1) + +static unsigned int pldn_dly = 1; + +int dim_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 = NULL; + unsigned int di_width, di_height, di_start_x, di_end_x, mv_offset; + unsigned int di_start_y, di_end_y, 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; + unsigned char mc_pre_flag = 0; + bool invert_mv = false; + static int post_index = -1; + unsigned char tmp_idx = 0; + struct di_dev_s *de_devp = get_dim_de_devp(); + struct di_hpst_s *pst = get_hw_pst(); + + unsigned char channel = pst->curr_ch; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + + dimp_inc(eDI_MP_post_cnt); + if (ppost->vscale_skip_flag) + return 0; + + get_vscale_skip_count(zoom_start_x_lines); + + if (IS_ERR_OR_NULL(di_buf)) + return 0; + else if (IS_ERR_OR_NULL(di_buf->di_buf_dup_p[0])) + return 0; + + hold_line = dimp_get(eDI_MP_post_hold_line); + di_pldn_buf = di_buf->di_buf_dup_p[pldn_dly]; + + if (di_que_is_in_que(channel, QUE_POST_FREE, di_buf) && + post_index != di_buf->index) { + post_index = di_buf->index; + PR_ERR("%s:post_buf[%d] is in post free list.\n", + __func__, di_buf->index); + return 0; + } + hpst_dbg_mem_pd_trig(0); + + if (ppost->toggle_flag && di_buf->di_buf_dup_p[1]) + top_bot_config(di_buf->di_buf_dup_p[1]); + + ppost->toggle_flag = false; + + ppost->cur_disp_index = di_buf->index; + + if (get_vpp_reg_update_flag(zoom_start_x_lines) || + dimp_get(eDI_MP_post_refresh)) + ppost->update_post_reg_flag = 1; + + 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 (!get_init_flag(channel) && IS_ERR_OR_NULL(ppost->keep_buf)) { + PR_ERR("%s 2:\n", __func__); + return 0; + } + dim_tr_ops.post_set(di_buf->vframe->omx_index); + /*dbg*/ + dim_ddbg_mod_save(eDI_DBG_MOD_POST_SETB, channel, ppost->frame_cnt); + dbg_post_cnt(channel, "ps1"); + 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 / (dimp_get(eDI_MP_di_vscale_skip_count_real) + 1); + /* make sure the height is even number */ + if (di_height % 2) { + /*for skip mode,post only half line-1*/ + if (!dimp_get(eDI_MP_post_wr_en) && + ((di_height > 150) && + (di_height < 1080)) && + dimp_get(eDI_MP_di_vscale_skip_count_real)) + di_height = di_height - 3; + else + di_height++; + } + #if 0 + dimh_post_ctrl(DI_HW_POST_CTRL_INIT, + (post_wr_en && post_wr_support)); + #endif + + if (Rd(DI_POST_SIZE) != ((di_width - 1) | ((di_height - 1) << 16)) || + ppost->buf_type != di_buf->di_buf_dup_p[0]->type || + (ppost->di_buf0_mif.luma_x_start0 != di_start_x) || + (ppost->di_buf0_mif.luma_y_start0 != di_start_y / 2)) { + dim_ddbg_mod_save(eDI_DBG_MOD_POST_RESIZE, channel, + ppost->frame_cnt);/*dbg*/ + ppost->buf_type = di_buf->di_buf_dup_p[0]->type; + + dimh_initial_di_post_2(di_width, di_height, + hold_line, + (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support))); + + if (!di_buf->di_buf_dup_p[0]->vframe || + !di_buf->vframe) { + PR_ERR("%s 3:\n", __func__); + return 0; + } + /* bit mode config */ + if (di_buf->vframe->bitdepth & BITDEPTH_Y10) { + if (di_buf->vframe->type & VIDTYPE_VIU_444) { + ppost->di_buf0_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2; + ppost->di_buf1_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2; + ppost->di_buf2_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2; + ppost->di_diwr_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 2; + + } else { + ppost->di_buf0_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1; + ppost->di_buf1_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1; + ppost->di_buf2_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1; + ppost->di_diwr_mif.bit_mode = + (di_buf->vframe->bitdepth & FULL_PACK_422_MODE) ? 3 : 1; + } + } else { + ppost->di_buf0_mif.bit_mode = 0; + ppost->di_buf1_mif.bit_mode = 0; + ppost->di_buf2_mif.bit_mode = 0; + ppost->di_diwr_mif.bit_mode = 0; + } + if (di_buf->vframe->type & VIDTYPE_VIU_444) { + ppost->di_buf0_mif.video_mode = 1; + ppost->di_buf1_mif.video_mode = 1; + ppost->di_buf2_mif.video_mode = 1; + } else { + ppost->di_buf0_mif.video_mode = 0; + ppost->di_buf1_mif.video_mode = 0; + ppost->di_buf2_mif.video_mode = 0; + } + if (ppost->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) { + ppost->di_buf0_mif.set_separate_en = 1; + ppost->di_buf1_mif.set_separate_en = 1; + ppost->di_buf2_mif.set_separate_en = 1; + } else { + ppost->di_buf0_mif.set_separate_en = 0; + ppost->di_buf1_mif.set_separate_en = 0; + ppost->di_buf2_mif.set_separate_en = 0; + } + ppost->di_buf0_mif.luma_y_start0 = di_start_y; + ppost->di_buf0_mif.luma_y_end0 = di_end_y; + } else { /* from vdin or local vframe process by di pre */ + ppost->di_buf0_mif.set_separate_en = 0; + ppost->di_buf0_mif.luma_y_start0 = + di_start_y >> 1; + ppost->di_buf0_mif.luma_y_end0 = di_end_y >> 1; + ppost->di_buf1_mif.set_separate_en = 0; + ppost->di_buf1_mif.luma_y_start0 = + di_start_y >> 1; + ppost->di_buf1_mif.luma_y_end0 = di_end_y >> 1; + ppost->di_buf2_mif.set_separate_en = 0; + ppost->di_buf2_mif.luma_y_end0 = di_end_y >> 1; + ppost->di_buf2_mif.luma_y_start0 = + di_start_y >> 1; + } + ppost->di_buf0_mif.luma_x_start0 = di_start_x; + ppost->di_buf0_mif.luma_x_end0 = di_end_x; + ppost->di_buf1_mif.luma_x_start0 = di_start_x; + ppost->di_buf1_mif.luma_x_end0 = di_end_x; + ppost->di_buf2_mif.luma_x_start0 = di_start_x; + ppost->di_buf2_mif.luma_x_end0 = di_end_x; + + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) { + if (de_devp->pps_enable && + dimp_get(eDI_MP_pps_position) == 0) { + dim_pps_config(0, di_width, di_height, + dimp_get(eDI_MP_pps_dstw), + dimp_get(eDI_MP_pps_dsth)); + ppost->di_diwr_mif.start_x = 0; + ppost->di_diwr_mif.end_x + = dimp_get(eDI_MP_pps_dstw) - 1; + ppost->di_diwr_mif.start_y = 0; + ppost->di_diwr_mif.end_y + = dimp_get(eDI_MP_pps_dsth) - 1; + } else { + ppost->di_diwr_mif.start_x = di_start_x; + ppost->di_diwr_mif.end_x = di_end_x; + ppost->di_diwr_mif.start_y = di_start_y; + ppost->di_diwr_mif.end_y = di_end_y; + } + } + + ppost->di_mtnprd_mif.start_x = di_start_x; + ppost->di_mtnprd_mif.end_x = di_end_x; + ppost->di_mtnprd_mif.start_y = di_start_y >> 1; + ppost->di_mtnprd_mif.end_y = di_end_y >> 1; + if (dimp_get(eDI_MP_mcpre_en)) { + ppost->di_mcvecrd_mif.start_x = di_start_x / 5; + mv_offset = (di_start_x % 5) ? (5 - di_start_x % 5) : 0; + ppost->di_mcvecrd_mif.vecrd_offset = + overturn ? (di_end_x + 1) % 5 : mv_offset; + ppost->di_mcvecrd_mif.start_y = + (di_start_y >> 1); + ppost->di_mcvecrd_mif.size_x = + (di_end_x + 1 + 4) / 5 - 1 - di_start_x / 5; + ppost->di_mcvecrd_mif.end_y = + (di_end_y >> 1); + } + ppost->update_post_reg_flag = 1; + /* if height decrease, mtn will not enough */ + if (di_buf->pd_config.global_mode != PULL_DOWN_BUF1 && + !dimp_get(eDI_MP_post_wr_en)) + di_buf->pd_config.global_mode = PULL_DOWN_EI; + } + +#ifdef DI_USE_FIXED_CANVAS_IDX +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA + if (is_vsync_rdma_enable()) { + ppost->canvas_id = ppost->next_canvas_id; + } else { + ppost->canvas_id = 0; + ppost->next_canvas_id = 1; + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) + ppost->canvas_id = + ppost->next_canvas_id; + } +#endif + /*post_blend = di_buf->pd_config.global_mode;*/ + dimp_set(eDI_MP_post_blend, di_buf->pd_config.global_mode); + dim_print("%s:ch[%d]\n", __func__, channel); + switch (dimp_get(eDI_MP_post_blend)) { + case PULL_DOWN_BLEND_0: + case PULL_DOWN_NORMAL: + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[ppost->canvas_id][0], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[2], -1, + di_post_idx[ppost->canvas_id][2]); + config_canvas_idx( + di_buf->di_buf_dup_p[0], + di_post_idx[ppost->canvas_id][1], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[2], + di_post_idx[ppost->canvas_id][3], -1); + if (dimp_get(eDI_MP_mcpre_en)) + config_mcvec_canvas_idx( + di_buf->di_buf_dup_p[2], + di_post_idx[ppost->canvas_id][4]); + break; + case PULL_DOWN_BLEND_2: + case PULL_DOWN_NORMAL_2: + config_canvas_idx( + di_buf->di_buf_dup_p[0], + di_post_idx[ppost->canvas_id][3], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[ppost->canvas_id][0], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[2], -1, + di_post_idx[ppost->canvas_id][2]); + config_canvas_idx( + di_buf->di_buf_dup_p[2], + di_post_idx[ppost->canvas_id][1], -1); + if (dimp_get(eDI_MP_mcpre_en)) + config_mcvec_canvas_idx( + di_buf->di_buf_dup_p[2], + di_post_idx[ppost->canvas_id][4]); + break; + case PULL_DOWN_MTN: + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[ppost->canvas_id][0], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[2], -1, + di_post_idx[ppost->canvas_id][2]); + config_canvas_idx( + di_buf->di_buf_dup_p[0], + di_post_idx[ppost->canvas_id][1], -1); + break; + case PULL_DOWN_BUF1:/* wave with buf1 */ + config_canvas_idx( + di_buf->di_buf_dup_p[1], + di_post_idx[ppost->canvas_id][0], -1); + config_canvas_idx( + di_buf->di_buf_dup_p[1], -1, + di_post_idx[ppost->canvas_id][2]); + config_canvas_idx( + di_buf->di_buf_dup_p[0], + di_post_idx[ppost->canvas_id][1], -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[ppost->canvas_id][0], -1); + break; + default: + break; + } + ppost->next_canvas_id = ppost->canvas_id ? 0 : 1; +#endif + if (!di_buf->di_buf_dup_p[1]) { + PR_ERR("%s 4:\n", __func__); + return 0; + } + if (!di_buf->di_buf_dup_p[1]->vframe || + !di_buf->di_buf_dup_p[0]->vframe) { + PR_ERR("%s 5:\n", __func__); + return 0; + } + + if (is_meson_txl_cpu() && overturn && di_buf->di_buf_dup_p[2]) { + /*sync from kernel 3.14 txl*/ + if (dimp_get(eDI_MP_post_blend) == PULL_DOWN_BLEND_2) + dimp_set(eDI_MP_post_blend, PULL_DOWN_BLEND_0); + else if (dimp_get(eDI_MP_post_blend) == PULL_DOWN_BLEND_0) + dimp_set(eDI_MP_post_blend, PULL_DOWN_BLEND_2); + } + + switch (dimp_get(eDI_MP_post_blend)) { + case PULL_DOWN_BLEND_0: + case PULL_DOWN_NORMAL: + post_field_num = + (di_buf->di_buf_dup_p[1]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + ppost->di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + ppost->di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + ppost->di_buf2_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[2]->nr_canvas_idx; + ppost->di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mtn_canvas_idx; + /*mc_pre_flag = is_meson_txl_cpu()?2:(overturn?0:1);*/ + if (is_meson_txl_cpu() && overturn) { + /* swap if1&if2 mean negation of mv for normal di*/ + tmp_idx = ppost->di_buf1_mif.canvas0_addr0; + ppost->di_buf1_mif.canvas0_addr0 = + ppost->di_buf2_mif.canvas0_addr0; + ppost->di_buf2_mif.canvas0_addr0 = tmp_idx; + } + mc_pre_flag = overturn ? 0 : 1; + if (di_buf->pd_config.global_mode == PULL_DOWN_NORMAL) { + post_blend_mode = 3; + /*if pulldown, mcdi_mcpreflag is 1,*/ + /*it means use previous field for MC*/ + /*else not pulldown,mcdi_mcpreflag is 2*/ + /*it means use forward & previous field for MC*/ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) + mc_pre_flag = 2; + } else { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) + mc_pre_flag = 1; + post_blend_mode = 1; + } + if (is_meson_txl_cpu() && overturn) + mc_pre_flag = 1; + + if (dimp_get(eDI_MP_mcpre_en)) { + ppost->di_mcvecrd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mcvec_canvas_idx; + } + blend_mtn_en = 1; + ei_en = 1; + dimp_set(eDI_MP_post_ei, 1); + post_blend_en = 1; + break; + case PULL_DOWN_BLEND_2: + case PULL_DOWN_NORMAL_2: + post_field_num = + (di_buf->di_buf_dup_p[1]->vframe->type & + VIDTYPE_TYPEMASK) + == VIDTYPE_INTERLACE_TOP ? 0 : 1; + ppost->di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + ppost->di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[2]->nr_canvas_idx; + ppost->di_buf2_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + ppost->di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mtn_canvas_idx; + if (is_meson_txl_cpu() && overturn) { + ppost->di_buf1_mif.canvas0_addr0 = + ppost->di_buf2_mif.canvas0_addr0; + } + if (dimp_get(eDI_MP_mcpre_en)) { + ppost->di_mcvecrd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mcvec_canvas_idx; + mc_pre_flag = is_meson_txl_cpu() ? 0 : + (overturn ? 1 : 0); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) + invert_mv = true; + else if (!overturn) + ppost->di_buf2_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[2]->nr_canvas_idx; + } + if (di_buf->pd_config.global_mode == PULL_DOWN_NORMAL_2) { + post_blend_mode = 3; + /*if pulldown, mcdi_mcpreflag is 1,*/ + /*it means use previous field for MC*/ + /*else not pulldown,mcdi_mcpreflag is 2*/ + /*it means use forward & previous field for MC*/ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) + mc_pre_flag = 2; + } else { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) + mc_pre_flag = 1; + post_blend_mode = 1; + } + blend_mtn_en = 1; + ei_en = 1; + dimp_set(eDI_MP_post_ei, 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; + ppost->di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + ppost->di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + ppost->di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[2]->mtn_canvas_idx; + post_blend_mode = 0; + blend_mtn_en = 1; + ei_en = 1; + dimp_set(eDI_MP_post_ei, 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; + ppost->di_buf0_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[1]->nr_canvas_idx; + ppost->di_mtnprd_mif.canvas_num = + di_buf->di_buf_dup_p[1]->mtn_canvas_idx; + ppost->di_buf1_mif.canvas0_addr0 = + di_buf->di_buf_dup_p[0]->nr_canvas_idx; + post_blend_mode = 1; + blend_mtn_en = 0; + ei_en = 0; + dimp_set(eDI_MP_post_ei, 0); + post_blend_en = 0; + break; + case PULL_DOWN_EI: + if (di_buf->di_buf_dup_p[1]) { + ppost->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; + ppost->di_buf0_mif.src_field_mode + = post_field_num; + } + post_blend_mode = 2; + blend_mtn_en = 0; + ei_en = 1; + dimp_set(eDI_MP_post_ei, 1); + post_blend_en = 0; + break; + default: + break; + } + + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) { + config_canvas_idx(di_buf, + di_post_idx[ppost->canvas_id][5], -1); + ppost->di_diwr_mif.canvas_num = di_buf->nr_canvas_idx; + 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->pd_config.global_mode == PULL_DOWN_BLEND_0 || + di_buf->pd_config.global_mode == PULL_DOWN_BLEND_2 || + di_buf->pd_config.global_mode == PULL_DOWN_NORMAL + )) { + post_blend_mode = 1; + blend_mtn_en = 0; + ei_en = 0; + dimp_set(eDI_MP_post_ei, 0); + post_blend_en = 0; + } + + if (dimp_get(eDI_MP_mcpre_en)) + ppost->di_mcvecrd_mif.blend_en = post_blend_en; + invert_mv = overturn ? (!invert_mv) : invert_mv; + if (ppost->update_post_reg_flag) { + dimh_enable_di_post_2( + &ppost->di_buf0_mif, + &ppost->di_buf1_mif, + &ppost->di_buf2_mif, + &ppost->di_diwr_mif, + &ppost->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, + dimp_get(eDI_MP_post_urgent), + (invert_mv ? 1 : 0), + dimp_get(eDI_MP_di_vscale_skip_count_real) + ); + if (dimp_get(eDI_MP_mcpre_en)) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dimh_enable_mc_di_post_g12( + &ppost->di_mcvecrd_mif, + dimp_get(eDI_MP_post_urgent), + overturn, (invert_mv ? 1 : 0)); + else + dimh_enable_mc_di_post( + &ppost->di_mcvecrd_mif, + dimp_get(eDI_MP_post_urgent), + overturn, (invert_mv ? 1 : 0)); + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + } + } else { + dimh_post_switch_buffer( + &ppost->di_buf0_mif, + &ppost->di_buf1_mif, + &ppost->di_buf2_mif, + &ppost->di_diwr_mif, + &ppost->di_mtnprd_mif, + &ppost->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, + dimp_get(eDI_MP_post_urgent), + (invert_mv ? 1 : 0), + dimp_get(eDI_MP_pulldown_enable), + dimp_get(eDI_MP_mcpre_en), + dimp_get(eDI_MP_di_vscale_skip_count_real) + ); + } + + if (is_meson_gxtvbb_cpu() || + is_meson_txl_cpu() || + is_meson_txlx_cpu() || + is_meson_gxlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || + is_meson_sm1_cpu()) { + if (di_cfg_top_get(eDI_CFG_ref_2) && + mc_pre_flag && + dimp_get(eDI_MP_post_wr_en)) { /*OTT-3210*/ + dbg_once("mc_old=%d\n", mc_pre_flag); + mc_pre_flag = 1; + } + dim_post_read_reverse_irq(overturn, mc_pre_flag, + post_blend_en ? dimp_get(eDI_MP_mcpre_en) : false); + /* disable mc for first 2 fieldes mv unreliable */ + if (di_buf->seq < 2) + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + } + if (dimp_get(eDI_MP_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_gxlx_cpu() || + is_meson_txl_cpu() || + is_meson_txlx_cpu()) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + } + +/* set pull down region (f(t-1) */ + + if (di_pldn_buf && + dimp_get(eDI_MP_pulldown_enable) && + !ppre->cur_prog_flag) { + unsigned short offset = (di_start_y >> 1); + + if (overturn) + offset = ((di_buf->vframe->height - di_end_y) >> 1); + else + offset = 0; + /*pulldown_vof_win_vshift*/ + get_ops_pd()->vof_win_vshift(&di_pldn_buf->pd_config, offset); + dimh_pulldown_vof_win_config(&di_pldn_buf->pd_config); + } + post_mif_sw(true); /*position?*/ + /*dimh_post_ctrl(DI_HW_POST_CTRL_RESET, di_ddr_en);*/ + /*add by wangfeng 2018-11-15*/ + dim_VSYNC_WR_MPEG_REG_BITS(DI_DIWR_CTRL, 1, 31, 1); + dim_VSYNC_WR_MPEG_REG_BITS(DI_DIWR_CTRL, 0, 31, 1); + /*ary add for post crash*/ + di_post_set_flow((dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)), + eDI_POST_FLOW_STEP2_START); + + if (ppost->update_post_reg_flag > 0) + ppost->update_post_reg_flag--; + + /*dbg*/ + dim_ddbg_mod_save(eDI_DBG_MOD_POST_SETE, channel, ppost->frame_cnt); + dbg_post_cnt(channel, "ps2"); + ppost->frame_cnt++; + + return 0; +} + +#ifndef DI_DEBUG_POST_BUF_FLOW +static void post_ready_buf_set(unsigned int ch, struct di_buf_s *di_buf) +{ + vframe_t *vframe_ret = NULL; + struct di_buf_s *nr_buf = NULL; + + vframe_ret = di_buf->vframe; + nr_buf = di_buf->di_buf_dup_p[1]; + if ((dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) && + (di_buf->process_fun_index != PROCESS_FUN_NULL)) { + #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + vframe_ret->canvas0_config[0].phy_addr = + di_buf->nr_adr; + vframe_ret->canvas0_config[0].width = + di_buf->canvas_width[NR_CANVAS], + vframe_ret->canvas0_config[0].height = + di_buf->canvas_height; + vframe_ret->canvas0_config[0].block_mode = 0; + vframe_ret->plane_num = 1; + vframe_ret->canvas0Addr = -1; + vframe_ret->canvas1Addr = -1; + if (di_mp_uit_get(eDI_MP_show_nrwr)) { + vframe_ret->canvas0_config[0].phy_addr = + nr_buf->nr_adr; + vframe_ret->canvas0_config[0].width = + nr_buf->canvas_width[NR_CANVAS]; + vframe_ret->canvas0_config[0].height = + nr_buf->canvas_height; + } + #else + config_canvas_idx(di_buf, di_wr_idx, -1); + vframe_ret->canvas0Addr = di_buf->nr_canvas_idx; + vframe_ret->canvas1Addr = di_buf->nr_canvas_idx; + if (di_mp_uit_get(eDI_MP_show_nrwr)) { + config_canvas_idx(nr_buf, + di_wr_idx, -1); + vframe_ret->canvas0Addr = di_wr_idx; + vframe_ret->canvas1Addr = di_wr_idx; + } + #endif + vframe_ret->early_process_fun = dim_do_post_wr_fun; + vframe_ret->process_fun = NULL; + + /* 2019-04-22 Suggestions from brian.zhu*/ + vframe_ret->mem_handle = NULL; + vframe_ret->type |= VIDTYPE_DI_PW; + /* 2019-04-22 */ + } +} + +#endif +void dim_post_de_done_buf_config(unsigned int channel) +{ + ulong irq_flag2 = 0; + struct di_buf_s *di_buf = NULL; + struct di_post_stru_s *ppost = get_post_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (!ppost->cur_post_buf) + return; + dbg_post_cnt(channel, "pd1"); + /*dbg*/ + dim_ddbg_mod_save(eDI_DBG_MOD_POST_DB, channel, ppost->frame_cnt); + + di_lock_irqfiq_save(irq_flag2); + queue_out(channel, ppost->cur_post_buf);/*? which que?post free*/ + di_buf = ppost->cur_post_buf; + + if (de_devp->pps_enable && dimp_get(eDI_MP_pps_position) == 0) { + di_buf->vframe->width = dimp_get(eDI_MP_pps_dstw); + di_buf->vframe->height = dimp_get(eDI_MP_pps_dsth); + } + + #ifdef DI_DEBUG_POST_BUF_FLOW + #else + post_ready_buf_set(channel, di_buf); + #endif + di_que_in(channel, QUE_POST_READY, ppost->cur_post_buf); + + #ifdef DI_DEBUG_POST_BUF_FLOW + #else + /*add by ary:*/ + recycle_post_ready_local(ppost->cur_post_buf, channel); + #endif + di_unlock_irqfiq_restore(irq_flag2); + dim_tr_ops.post_ready(di_buf->vframe->omx_index); + pw_vf_notify_receiver(channel, + VFRAME_EVENT_PROVIDER_VFRAME_READY, NULL); + ppost->cur_post_buf = NULL; + /*dbg*/ + dim_ddbg_mod_save(eDI_DBG_MOD_POST_DE, channel, ppost->frame_cnt); + dbg_post_cnt(channel, "pd2"); +} + +#if 0 +static void di_post_process(unsigned int channel) +{ + struct di_buf_s *di_buf = NULL; + vframe_t *vf_p = NULL; + struct di_post_stru_s *ppost = get_post_stru(channel); + + if (ppost->post_de_busy) + return; + if (queue_empty(channel, QUEUE_POST_DOING)) { + ppost->post_peek_underflow++; + return; + } + + di_buf = get_di_buf_head(channel, QUEUE_POST_DOING); + if (dim_check_di_buf(di_buf, 20, channel)) + return; + vf_p = di_buf->vframe; + if (ppost->run_early_proc_fun_flag) { + if (vf_p->early_process_fun) + vf_p->early_process_fun = dim_do_post_wr_fun; + } + if (di_buf->process_fun_index) { + ppost->post_wr_cnt++; + dim_post_process(di_buf, 0, vf_p->width - 1, + 0, vf_p->height - 1, vf_p); + ppost->post_de_busy = 1; + ppost->irq_time = cur_to_msecs(); + } else { + ppost->de_post_process_done = 1; + } + ppost->cur_post_buf = di_buf; +} +#endif + +static void recycle_vframe_type_post(struct di_buf_s *di_buf, + unsigned int channel) +{ + int i; + + if (!di_buf) { + PR_ERR("%s:\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(channel, di_buf->di_buf[i], QUEUE_RECYCLE); + dim_print("%s: ch[%d]:di_buf[%d],type=%d\n", __func__, + channel, di_buf->di_buf[i]->index, + di_buf->di_buf[i]->type); + } + } + queue_out(channel, di_buf); /* remove it from display_list_head */ + if (di_buf->queue_index != -1) { + PR_ERR("qout err:index[%d],typ[%d],qindex[%d]\n", + di_buf->index, di_buf->type, di_buf->queue_index); + /* queue_out_dbg(channel, di_buf);*/ + } + di_buf->invert_top_bot_flag = 0; + di_que_in(channel, QUE_POST_FREE, di_buf); +} + +void recycle_post_ready_local(struct di_buf_s *di_buf, unsigned int channel) +{ + int i; + + if (di_buf->type != VFRAME_TYPE_POST) + return; + + if (di_buf->process_fun_index == PROCESS_FUN_NULL) /*bypass?*/ + 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(channel, di_buf->di_buf[i], QUEUE_RECYCLE); + dim_print("%s: ch[%d]:di_buf[%d],type=%d\n", + __func__, + channel, + di_buf->di_buf[i]->index, + di_buf->di_buf[i]->type); + di_buf->di_buf[i] = NULL; + } + } +} + +#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; + + dim_print("%s:%d ", func, line); + for (i = 0; i < 2; i++) { + if (di_buf->di_buf[i]) + dim_print("%s[%d]<%d>=>recycle_list; ", + vframe_type_name[di_buf->di_buf[i]->type], + di_buf->di_buf[i]->index, i); + } + dim_print("%s[%d] =>post_free_list\n", + vframe_type_name[di_buf->type], di_buf->index); +} +#endif + +static unsigned int pldn_dly1 = 1; +static void set_pulldown_mode(struct di_buf_s *di_buf, unsigned int channel) +{ + struct di_buf_s *pre_buf_p = di_buf->di_buf_dup_p[pldn_dly1]; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXBB)) { + if (dimp_get(eDI_MP_pulldown_enable) && + !ppre->cur_prog_flag) { + if (pre_buf_p) { + di_buf->pd_config.global_mode = + pre_buf_p->pd_config.global_mode; + } else { + /* ary add 2019-06-19*/ + di_buf->pd_config.global_mode + = PULL_DOWN_EI; + PR_ERR("[%s]: index out of range.\n", + __func__); + } + } else { + di_buf->pd_config.global_mode + = PULL_DOWN_NORMAL; + } + } +} + +static void drop_frame(int check_drop, int throw_flag, struct di_buf_s *di_buf, + unsigned int channel) +{ + ulong irq_flag2 = 0; + int i = 0, drop_flag = 0; + struct di_post_stru_s *ppost = get_post_stru(channel); + + di_lock_irqfiq_save(irq_flag2); + if ((frame_count == 0) && check_drop) + ppost->start_pts = di_buf->vframe->pts; + if ((check_drop && + (frame_count < dimp_get(eDI_MP_start_frame_drop_count))) || + throw_flag) { + drop_flag = 1; + } else { + if (check_drop && (frame_count + == dimp_get(eDI_MP_start_frame_drop_count))) { + if ((ppost->start_pts) && + (di_buf->vframe->pts == 0)) + di_buf->vframe->pts = ppost->start_pts; + ppost->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(channel, di_buf, QUEUE_TMP); + recycle_vframe_type_post(di_buf, channel); +#ifdef DI_BUFFER_DEBUG + recycle_vframe_type_post_print( + di_buf, __func__, + __LINE__); +#endif + } else { + dim_print("%s:wr_en[%d],support[%d]\n", __func__, + dimp_get(eDI_MP_post_wr_en), + dimp_get(eDI_MP_post_wr_support)); + + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) + queue_in(channel, di_buf, QUEUE_POST_DOING); + else + di_que_in(channel, QUE_POST_READY, di_buf); + + dim_tr_ops.post_do(di_buf->vframe->omx_index); + dim_print("di:ch[%]:%dth %s[%d] => post ready %u ms.\n", + channel, + frame_count, + 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); +} + +int dim_process_post_vframe(unsigned int channel) +{ +/* + * 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 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; + /* new que int ready_count = list_count(channel, QUEUE_PRE_READY);*/ + int ready_count = di_que_list_count(channel, QUE_PRE_READY); + bool check_drop = false; + unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/ + unsigned int psize; /*new que*/ + +#if 1 + if (di_que_is_empty(channel, QUE_POST_FREE)) + return 0; + /*add : for now post buf only 3.*/ + if (list_count(channel, QUEUE_POST_DOING) > 2) + return 0; +#else + /*for post write mode ,need reserved a post free buf;*/ + if (di_que_list_count(channel, QUE_POST_FREE) < 2) + return 0; +#endif + if (ready_count == 0) + return 0; + + ready_di_buf = di_que_peek(channel, QUE_PRE_READY); + if (!ready_di_buf || !ready_di_buf->vframe) { + pr_dbg("%s:Error1\n", __func__); + + if (recovery_flag == 0) + recovery_log_reason = 16; + + recovery_flag++; + return 0; + } + dim_print("%s:1 ready_count[%d]:post_proc_flag[%d]\n", __func__, + ready_count, ready_di_buf->post_proc_flag); + if ((ready_di_buf->post_proc_flag) && + (ready_count >= buffer_keep_count)) { + i = 0; + + di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, tmpa[itmp]); + /* 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); + + di_buf = di_que_out_to_di_buf(channel, QUE_POST_FREE); + if (dim_check_di_buf(di_buf, 17, channel)) { + di_unlock_irqfiq_restore(irq_flag2); + return 0; + } + + di_unlock_irqfiq_restore(irq_flag2); + + i = 0; + + di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); + + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, tmpa[itmp]); + dim_print("di:keep[%d]:t[%d]:idx[%d]\n", + i, tmpa[itmp], p->index); + di_buf->di_buf_dup_p[i++] = p; + + if (i >= buffer_keep_count) + break; + } + if (i < buffer_keep_count) { + PR_ERR("%s:3\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(channel, di_buf->di_buf[0]); + di_lock_irqfiq_save(irq_flag2); + queue_in(channel, di_buf, QUEUE_TMP); + recycle_vframe_type_post(di_buf, channel); + + di_unlock_irqfiq_restore(irq_flag2); + dim_print("%s : ", __func__); +#ifdef DI_BUFFER_DEBUG + dim_print("%s : ", __func__); +#endif + } else { + if (di_buf->di_buf_dup_p[1]->post_proc_flag + == 2) { + di_buf->pd_config.global_mode + = PULL_DOWN_BLEND_2; + /* blend with di_buf->di_buf_dup_p[2] */ + } else { + set_pulldown_mode(di_buf, channel); + } + di_buf->vframe->type = + VIDTYPE_PROGRESSIVE | + VIDTYPE_VIU_422 | + VIDTYPE_VIU_SINGLE_PLANE | + VIDTYPE_VIU_FIELD | + VIDTYPE_PRE_INTERLACE; + + di_buf->vframe->width + = di_buf->di_buf_dup_p[1]->width_bk; + + 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 | + VIDTYPE_PRE_INTERLACE; + 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 (dimp_get(eDI_MP_debug_blend_mode) != -1) + di_buf->pd_config.global_mode + = dimp_get(eDI_MP_debug_blend_mode); + + di_buf->vframe->process_fun = +((dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) ? + NULL : dim_post_process); + di_buf->process_fun_index = PROCESS_FUN_DI; + inc_post_ref_count(di_buf); + } + di_buf->di_buf[0] /*ary:di_buf_di_buf*/ + = di_buf->di_buf_dup_p[0]; + di_buf->di_buf[1] = NULL; + queue_out(channel, 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, channel); + + frame_count++; +#ifdef DI_BUFFER_DEBUG + dim_print("%s : ", __func__); +#endif + if (!(dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support))) + pw_vf_notify_receiver(channel, +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 || + dimp_get(eDI_MP_bypass_post_state) + ){ + int vframe_process_count = 1; +#ifdef DET3D + int dual_vframe_flag = 0; + + if ((ppre->vframe_interleave_flag && + ready_di_buf->left_right) || + (dimp_get(eDI_MP_bypass_post) & 0x100)) { + dual_vframe_flag = 1; + vframe_process_count = 2; + } +#endif + if (dimp_get(eDI_MP_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); + + di_buf = di_que_out_to_di_buf(channel, QUE_POST_FREE); + if (dim_check_di_buf(di_buf, 19, channel)) { + di_unlock_irqfiq_restore(irq_flag2); + return 0; + } + + di_unlock_irqfiq_restore(irq_flag2); + + i = 0; + + di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); + + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, + tmpa[itmp]); + 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_ERR("%s:6\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) && + ((dimp_get(eDI_MP_skip_top_bot) == 1) || + (dimp_get(eDI_MP_skip_top_bot) == 2))) { + unsigned int frame_type = + di_buf->di_buf_dup_p[1]-> + vframe->type & + VIDTYPE_TYPEMASK; + if (dimp_get(eDI_MP_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 ( + dimp_get(eDI_MP_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->width = di_buf_i->width_bk; + di_buf->vframe->private_data = di_buf; + + if (ready_di_buf->new_format_flag && + (ready_di_buf->type == VFRAME_TYPE_IN)) { + pr_info("DI:ch[%d],%d disable post.\n", + channel, + __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; + } + dim_print("%s:2\n", __func__); + 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 += (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) ? NULL : + dim_post_process; + di_buf->process_fun_index = + PROCESS_FUN_DI; + di_buf->pd_config.global_mode + = PULL_DOWN_EI; + } else { + di_buf->vframe->process_fun = + NULL; + di_buf->process_fun_index = + PROCESS_FUN_NULL; + di_buf->pd_config.global_mode = + PULL_DOWN_NORMAL; + } + di_buf->di_buf[0] = ready_di_buf; + di_buf->di_buf[1] = NULL; + queue_out(channel, ready_di_buf); + +#ifdef DET3D + if (dual_vframe_flag) { + di_buf->di_buf[1] = + di_buf->di_buf_dup_p[1]; + queue_out(channel, di_buf->di_buf[1]); + } +#endif + drop_frame(check_drop, + di_buf->di_buf[0]->throw_flag, + di_buf, channel); + + frame_count++; +#ifdef DI_BUFFER_DEBUG + dim_print( + "%s : ", + __func__); +#endif + ret = 1; + pw_vf_notify_receiver(channel, + 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 = + (dimp_get(eDI_MP_prog_proc_config) >> 1) & 0x3; + di_lock_irqfiq_save(irq_flag2); + + di_buf = di_que_out_to_di_buf(channel, QUE_POST_FREE); + if (dim_check_di_buf(di_buf, 20, channel)) { + di_unlock_irqfiq_restore(irq_flag2); + return 0; + } + + di_unlock_irqfiq_restore(irq_flag2); + + i = 0; + + di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); + + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(channel, tmpa[itmp]); + di_buf->di_buf_dup_p[i++] = p; + if (i >= 2) { + di_buf->di_buf_dup_p[i] = NULL; + break; + } + } + if (i < 2) { + PR_ERR("%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 | + VIDTYPE_PRE_INTERLACE; + 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->pd_config.global_mode = + PULL_DOWN_BUF1; + di_buf->vframe->process_fun = +(dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) ? NULL : + dim_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 | + VIDTYPE_PRE_INTERLACE; + di_buf->vframe->height >>= 1; + + di_buf->vframe->width + = di_buf->di_buf_dup_p[0]->width_bk; + 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(channel, 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; + queue_in(channel, di_buf, QUEUE_TMP); + recycle_vframe_type_post(di_buf, channel); + 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(channel, di_buf->di_buf[1]); + + drop_frame( + dimp_get(eDI_MP_check_start_drop_prog), + (di_buf->di_buf_dup_p[0]->throw_flag) || + (di_buf->di_buf_dup_p[1]->throw_flag), + di_buf, channel); + } + frame_count++; +#ifdef DI_BUFFER_DEBUG + dim_print("%s : ", __func__); +#endif + ret = 1; + pw_vf_notify_receiver(channel, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); + } + } + +#ifdef DI_BUFFER_DEBUG + if (di_buf) { + dim_print("%s[%d](", + vframe_type_name[di_buf->type], di_buf->index); + for (i = 0; i < 2; i++) { + if (di_buf->di_buf[i]) + dim_print("%s[%d],", + vframe_type_name[di_buf->di_buf[i]->type], + di_buf->di_buf[i]->index); + } + dim_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)) + dim_print("=> recycle_list\n"); + else + dim_print("=> post_ready_list\n"); + } +#endif + return ret; +} + +/* + * di task + */ +void dim_unreg_process(unsigned int channel) +{ + unsigned long start_jiffes = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + pr_info("%s unreg start %d.\n", __func__, get_reg_flag(channel)); + if (get_reg_flag(channel)) { + start_jiffes = jiffies_64; + di_vframe_unreg(channel); + pr_dbg("%s vf unreg cost %u ms.\n", __func__, + jiffies_to_msecs(jiffies_64 - start_jiffes)); + unreg_cnt++; + if (unreg_cnt > 0x3fffffff) + unreg_cnt = 0; + pr_dbg("%s unreg stop %d.\n", __func__, get_reg_flag(channel)); + + } else { + ppre->force_unreg_req_flag = 0; + ppre->disable_req_flag = 0; + recovery_flag = 0; + } +} + +void di_unreg_setting(void) +{ + unsigned int mirror_disable = get_blackout_policy(); + + if (!get_hw_reg_flg()) { + PR_ERR("%s:have setting?do nothing\n", __func__); + return; + } + + pr_info("%s:\n", __func__); + /*set flg*/ + set_hw_reg_flg(false); + + dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en)); + post_close_new(); /*2018-11-29*/ + dimh_afbc_reg_sw(false); + dimh_hw_uninit(); + if (is_meson_txlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || + is_meson_sm1_cpu()) { + dim_pre_gate_control(false, dimp_get(eDI_MP_mcpre_en)); + get_ops_nr()->nr_gate_control(false); + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { + dim_DI_Wr(DI_CLKG_CTRL, 0x80f60000); + dim_DI_Wr(DI_PRE_CTRL, 0); + } else { + dim_DI_Wr(DI_CLKG_CTRL, 0xf60000); + } + /*ary add for switch to post wr, can't display*/ + pr_info("di: patch dimh_disable_post_deinterlace_2\n"); + dimh_disable_post_deinterlace_2(); + /* nr/blend0/ei0/mtn0 clock gate */ + + dim_hw_disable(dimp_get(eDI_MP_mcpre_en)); + + if (is_meson_txlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || + is_meson_sm1_cpu()) { + dimh_enable_di_post_mif(GATE_OFF); + dim_post_gate_control(false); + dim_top_gate_control(false, false); + } else { + dim_DI_Wr(DI_CLKG_CTRL, 0x80000000); + } + if (!is_meson_gxl_cpu() && + !is_meson_gxm_cpu() && + !is_meson_gxbb_cpu() && + !is_meson_txlx_cpu()) + diext_clk_b_sw(false); + pr_info("%s disable di mirror image.\n", __func__); + +#if 0 + if (mirror_disable) { + /*no mirror:*/ + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) + dim_set_power_control(0); + + } else { + /*have mirror:*/ + } +#else /*0624?*/ + if ((dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) || + mirror_disable) { + /*diwr_set_power_control(0);*/ + hpst_mem_pd_sw(0); + } + if (mirror_disable) + hpst_vd1_sw(0); +#endif + + #if 0 /*tmp*/ + if (post_wr_en && post_wr_support) + dim_set_power_control(0); + #endif + + disp_frame_count = 0;/* debug only*/ +} + +void di_unreg_variable(unsigned int channel) +{ + ulong irq_flag2 = 0; + unsigned int mirror_disable = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + +#if (defined ENABLE_SPIN_LOCK_ALWAYS) + ulong flags = 0; + + spin_lock_irqsave(&plist_lock, flags); +#endif + pr_info("%s:\n", __func__); + set_init_flag(channel, false); /*init_flag = 0;*/ + mirror_disable = get_blackout_policy(); + di_lock_irqfiq_save(irq_flag2); + dim_print("%s: dim_uninit_buf\n", __func__); + dim_uninit_buf(mirror_disable, channel); +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA + if (di_pre_rdma_enable) + rdma_clear(de_devp->rdma_handle); +#endif + get_ops_mtn()->adpative_combing_exit(); + + di_unlock_irqfiq_restore(irq_flag2); + +#if (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_unlock_irqrestore(&plist_lock, flags); +#endif + dimh_patch_post_update_mc_sw(DI_MC_SW_REG, false); + + ppre->force_unreg_req_flag = 0; + ppre->disable_req_flag = 0; + recovery_flag = 0; + ppre->cur_prog_flag = 0; + + if (de_devp->flag_cma == 1 || + de_devp->flag_cma == 3 || + de_devp->flag_cma == 4) + dip_wq_cma_run(channel, false); + + sum_g_clear(channel); + sum_p_clear(channel); + dbg_reg("%s:end\n", __func__); +} + +void dim_unreg_process_irq(unsigned int channel) +{ + ulong irq_flag2 = 0; + unsigned int mirror_disable = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + +#if (defined ENABLE_SPIN_LOCK_ALWAYS) + ulong flags = 0; + + spin_lock_irqsave(&plist_lock, flags); +#endif + pr_info("%s:warn:not use\n", __func__); + set_init_flag(channel, false); /*init_flag = 0;*/ + mirror_disable = 1; /*get_blackout_policy()*/; + di_lock_irqfiq_save(irq_flag2); + dim_print("%s: dim_uninit_buf\n", __func__); + dim_uninit_buf(mirror_disable, channel); +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA + if (di_pre_rdma_enable) + rdma_clear(de_devp->rdma_handle); +#endif + get_ops_mtn()->adpative_combing_exit(); + dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en)); + dimh_afbc_reg_sw(false); + dimh_hw_uninit(); + if (is_meson_txlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_sm1_cpu() || + is_meson_tm2_cpu()) { + dim_pre_gate_control(false, dimp_get(eDI_MP_mcpre_en)); + get_ops_nr()->nr_gate_control(false); + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { + dim_DI_Wr(DI_CLKG_CTRL, 0x80f60000); + dim_DI_Wr(DI_PRE_CTRL, 0); + } else { + dim_DI_Wr(DI_CLKG_CTRL, 0xf60000); + } + /*ary add for switch to post wr, can't display*/ + pr_info("di: patch dimh_disable_post_deinterlace_2\n"); + dimh_disable_post_deinterlace_2(); + +/* nr/blend0/ei0/mtn0 clock gate */ + if (mirror_disable) { + dim_hw_disable(dimp_get(eDI_MP_mcpre_en)); + if (is_meson_txlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_sm1_cpu() || + is_meson_tm2_cpu()) { + dimh_enable_di_post_mif(GATE_OFF); + dim_post_gate_control(false); + dim_top_gate_control(false, false); + } else { + dim_DI_Wr(DI_CLKG_CTRL, 0x80000000); + } + if (!is_meson_gxl_cpu() && + !is_meson_gxm_cpu() && + !is_meson_gxbb_cpu() && + !is_meson_txlx_cpu()) + diext_clk_b_sw(false); + + pr_info("%s disable di mirror image.\n", __func__); + } + if (dimp_get(eDI_MP_post_wr_en) && dimp_get(eDI_MP_post_wr_support)) + dim_set_power_control(0); + di_unlock_irqfiq_restore(irq_flag2); + +#if (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_unlock_irqrestore(&plist_lock, flags); +#endif + dimh_patch_post_update_mc_sw(DI_MC_SW_REG, false); + ppre->force_unreg_req_flag = 0; + ppre->disable_req_flag = 0; + recovery_flag = 0; + ppre->cur_prog_flag = 0; + +#if 0 +#ifdef CONFIG_CMA + if (de_devp->flag_cma == 1) { + pr_dbg("%s:cma release req time: %d ms\n", + __func__, jiffies_to_msecs(jiffies)); + ppre->cma_release_req = 1; + up(get_sema()); + } +#endif +#else + if (de_devp->flag_cma == 1) + dip_wq_cma_run(channel, false); + +#endif +} + +void diext_clk_b_sw(bool on) +{ + if (on) + ext_ops.switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, + VPU_CLK_GATE_ON); + else + ext_ops.switch_vpu_clk_gate_vmod(VPU_VPU_CLKB, + VPU_CLK_GATE_OFF); +} + +void dim_reg_process(unsigned int channel) +{ + /*get vout information first time*/ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (get_reg_flag(channel)) + return; + di_vframe_reg(channel); + + ppre->bypass_flag = false; + reg_cnt++; + if (reg_cnt > 0x3fffffff) + reg_cnt = 0; + dim_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; + unsigned int channel = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (IS_ERR_OR_NULL(di_devp)) + return; + if (di_devp->rdma_handle <= 0) { + PR_ERR("%s rdma handle %d error.\n", __func__, + di_devp->rdma_handle); + return; + } + if (dimp_get(eDI_MP_di_printk_flag)) + pr_dbg("%s...%d.\n", __func__, + ppre->field_count_for_cont); +} + +static struct rdma_op_s di_rdma_op = { + di_rdma_irq, + NULL +}; +#endif + +void dim_rdma_init(void) +{ +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA + struct di_dev_s *de_devp = get_dim_de_devp(); +/* rdma handle */ + if (di_pre_rdma_enable) { + di_rdma_op.arg = de_devp; + de_devp->rdma_handle = rdma_register(&di_rdma_op, + de_devp, RDMA_TABLE_SIZE); + } + +#endif +} + +void dim_rdma_exit(void) +{ +#ifdef CONFIG_AMLOGIC_MEDIA_RDMA + struct di_dev_s *de_devp = get_dim_de_devp(); + + /* rdma handle */ + if (de_devp->rdma_handle > 0) + rdma_unregister(de_devp->rdma_handle); +#endif +} + +static void di_load_pq_table(void) +{ + struct di_pq_parm_s *pos = NULL, *tmp = NULL; + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (atomic_read(&de_devp->pq_flag) == 0 && + (de_devp->flags & DI_LOAD_REG_FLAG)) { + atomic_set(&de_devp->pq_flag, 1); + list_for_each_entry_safe(pos, tmp, + &de_devp->pq_table_list, list) { + dimh_load_regs(pos); + list_del(&pos->list); + di_pq_parm_destroy(pos); + } + de_devp->flags &= ~DI_LOAD_REG_FLAG; + atomic_set(&de_devp->pq_flag, 0); + } +} + +static void di_pre_size_change(unsigned short width, + unsigned short height, + unsigned short vf_type, + unsigned int channel) +{ + unsigned int blkhsize = 0; + int pps_w = 0, pps_h = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + + /*pr_info("%s:\n", __func__);*/ + /*debug only:*/ + /*di_pause(channel, true);*/ + get_ops_nr()->nr_all_config(width, height, vf_type); + #ifdef DET3D + /*det3d_config*/ + get_ops_3d()->det3d_config(dimp_get(eDI_MP_det3d_en) ? 1 : 0); + #endif + if (dimp_get(eDI_MP_pulldown_enable)) { + /*pulldown_init(width, height);*/ + get_ops_pd()->init(width, height); + dimh_init_field_mode(height); + + if (is_meson_txl_cpu() || + is_meson_txlx_cpu() || + is_meson_gxlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || + is_meson_sm1_cpu()) + dim_film_mode_win_config(width, height); + } + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + dimh_combing_pd22_window_config(width, height); + dim_RDMA_WR(DI_PRE_SIZE, (width - 1) | + ((height - 1) << 16)); + + if (dimp_get(eDI_MP_mcpre_en)) { + blkhsize = (width + 4) / 5; + dim_RDMA_WR(MCDI_HV_SIZEIN, height + | (width << 16)); + dim_RDMA_WR(MCDI_HV_BLKSIZEIN, (overturn ? 3 : 0) << 30 + | blkhsize << 16 | height); + dim_RDMA_WR(MCDI_BLKTOTAL, blkhsize * height); + if (is_meson_gxlx_cpu()) { + dim_RDMA_WR(MCDI_PD_22_CHK_FLG_CNT, 0); + dim_RDMA_WR(MCDI_FIELD_MV, 0); + } + } + if (channel == 0) + di_load_pq_table(); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dim_RDMA_WR(DI_PRE_GL_CTRL, 0x80000005); + if (de_devp->nrds_enable) + dim_nr_ds_init(width, height); + if (de_devp->pps_enable && dimp_get(eDI_MP_pps_position)) { + pps_w = ppre->cur_width; + pps_h = ppre->cur_height >> 1; + dim_pps_config(1, pps_w, pps_h, + dimp_get(eDI_MP_pps_dstw), + (dimp_get(eDI_MP_pps_dsth) >> 1)); + } + if (is_meson_sm1_cpu() || is_meson_tm2_cpu()) { + if (de_devp->h_sc_down_en) { + pps_w = ppre->cur_width; + dim_inp_hsc_setting(pps_w, + di_mp_uit_get(eDI_MP_pre_hsc_down_width)); + } else { + dim_inp_hsc_setting(ppre->cur_width, + ppre->cur_width); + } + } + #if 0 + dimh_interrupt_ctrl(ppre->madi_enable, + det3d_en ? 1 : 0, + de_devp->nrds_enable, + post_wr_en, + ppre->mcdi_enable); + #else + /*dimh_int_ctr(0, 0, 0, 0, 0, 0);*/ + dimh_int_ctr(1, ppre->madi_enable, + dimp_get(eDI_MP_det3d_en) ? 1 : 0, + de_devp->nrds_enable, + dimp_get(eDI_MP_post_wr_en), + ppre->mcdi_enable); + #endif +} + +static bool need_bypass(struct vframe_s *vf) +{ + if (vf->type & VIDTYPE_MVC) + return true; + + if (vf->source_type == VFRAME_SOURCE_TYPE_PPMGR) + return true; + + if (vf->type & VIDTYPE_VIU_444) + return true; + + if (vf->type & VIDTYPE_PIC) + return true; +#if 0 + if (vf->type & VIDTYPE_COMPRESS) + return true; +#else + /*support G12A and TXLX platform*/ + if (vf->type & VIDTYPE_COMPRESS) { + if (!dimh_afbc_is_supported()) + return true; + if ((vf->compHeight > (default_height + 8)) || + (vf->compWidth > default_width)) + return true; + } +#endif + if ((vf->width > default_width) || + (vf->height > (default_height + 8))) + return true; +#if 1 + if (vf_type_is_prog(vf->type)) {/*temp bypass p*/ + return true; + } +#endif + /*true bypass for 720p above*/ + if ((vf->flag & VFRAME_FLAG_GAME_MODE) && + (vf->width > 720)) + return true; + + return false; +} + +/********************************* + * + * setting register only call when + * from di_reg_process_irq + *********************************/ +void di_reg_setting(unsigned int channel, struct vframe_s *vframe) +{ + unsigned short nr_height = 0, first_field_type; + struct di_dev_s *de_devp = get_dim_de_devp(); + + pr_info("%s:ch[%d]:for first ch reg:\n", __func__, channel); + + if (get_hw_reg_flg()) { + PR_ERR("%s:have setting?do nothing\n", __func__); + return; + } + /*set flg*/ + set_hw_reg_flg(true); + + diext_clk_b_sw(true); + + dim_ddbg_mod_save(eDI_DBG_MOD_REGB, channel, 0); + + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) + dim_set_power_control(1); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) { + /*if (!use_2_interlace_buff) {*/ + if (1) { + dim_top_gate_control(true, true); + dim_post_gate_control(true); + /* freerun for reg configuration */ + dimh_enable_di_post_mif(GATE_AUTO); + } else { + dim_top_gate_control(true, false); + } + de_devp->flags |= DI_VPU_CLKB_SET; + #if 1 /*set clkb to max */ + if (is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || + is_meson_sm1_cpu() + ) { + #ifdef CLK_TREE_SUPPORT + clk_set_rate(de_devp->vpu_clkb, + de_devp->clkb_max_rate); + #endif + } + #endif + dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en)); + dim_pre_gate_control(true, dimp_get(eDI_MP_mcpre_en)); + dim_rst_protect(true);/*2019-01-22 by VLSI feng.wang*/ + dim_pre_nr_wr_done_sel(true); + get_ops_nr()->nr_gate_control(true); + } else { + /* if mcdi enable DI_CLKG_CTRL should be 0xfef60000 */ + dim_DI_Wr(DI_CLKG_CTRL, 0xfef60001); + /* nr/blend0/ei0/mtn0 clock gate */ + } + /*--------------------------*/ + dim_init_setting_once(); + /*--------------------------*/ + /*di_post_reset();*/ /*add by feijun 2018-11-19 */ + post_mif_sw(false); + post_dbg_contr(); + /*--------------------------*/ + + nr_height = (vframe->height >> 1);/*temp*/ + /*--------------------------*/ + dimh_calc_lmv_init(); + first_field_type = (vframe->type & VIDTYPE_TYPEMASK); + di_pre_size_change(vframe->width, nr_height, + first_field_type, channel); + get_ops_nr()->cue_int(); + dim_ddbg_mod_save(eDI_DBG_MOD_REGE, channel, 0); + + /*--------------------------*/ + /*test*/ + dimh_int_ctr(0, 0, 0, 0, 0, 0); +} + +/********************************* + * + * setting variable + * from di_reg_process_irq + * + *********************************/ +void di_reg_variable(unsigned int channel, struct vframe_s *vframe) +{ + ulong irq_flag2 = 0; + #ifndef RUN_DI_PROCESS_IN_IRQ + ulong flags = 0; + #endif + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + + 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; + + dbg_reg("%s:\n", __func__); + + dim_print("%s:0x%p\n", __func__, vframe); + if (vframe) { + dip_init_value_reg(channel);/*add 0404 for post*/ + dim_ddbg_mod_save(eDI_DBG_MOD_RVB, channel, 0); + if (need_bypass(vframe) || + ((dimp_get(eDI_MP_di_debug_flag) >> 20) & 0x1)) { + if (!ppre->bypass_flag) { + pr_info("DI %ux%u-0x%x.\n", + vframe->width, + vframe->height, + vframe->type); + } + ppre->bypass_flag = true; + dimh_patch_post_update_mc_sw(DI_MC_SW_OTHER, false); + return; + + ppre->bypass_flag = false; + } + /* patch for vdin progressive input */ + if ((is_from_vdin(vframe) && + is_progressive(vframe)) + #ifdef DET3D + || dimp_get(eDI_MP_det3d_en) + #endif + || (dimp_get(eDI_MP_use_2_interlace_buff) & 0x2) + ) { + dimp_set(eDI_MP_use_2_interlace_buff, 1); + } else { + dimp_set(eDI_MP_use_2_interlace_buff, 0); + } + de_devp->nrds_enable = dimp_get(eDI_MP_nrds_en); + de_devp->pps_enable = dimp_get(eDI_MP_pps_en); + /*di pre h scaling down: sm1 tm2*/ + de_devp->h_sc_down_en = di_mp_uit_get(eDI_MP_pre_hsc_down_en); + + if (dimp_get(eDI_MP_di_printk_flag) & 2) + dimp_set(eDI_MP_di_printk_flag, 1); + + dim_print("%s: vframe come => di_init_buf\n", __func__); + + if (de_devp->flag_cma == 0 && !de_devp->mem_flg) + dim_rev_mem_check(); + + /*(is_progressive(vframe) && (prog_proc_config & 0x10)) {*/ + if (0) { +#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); + /* + * 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, channel); + + di_unlock_irqfiq_restore(irq_flag2); + +#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); + /* + * 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, channel); + + di_unlock_irqfiq_restore(irq_flag2); + +#if (!(defined RUN_DI_PROCESS_IN_IRQ)) || (defined ENABLE_SPIN_LOCK_ALWAYS) + spin_unlock_irqrestore(&plist_lock, flags); +#endif + } + + ppre->mtn_status = + get_ops_mtn()->adpative_combing_config(vframe->width, + (vframe->height >> 1), + (vframe->source_type), + is_progressive(vframe), + vframe->sig_fmt); + + dimh_patch_post_update_mc_sw(DI_MC_SW_REG, true); + di_sum_reg_init(channel); + + set_init_flag(channel, true);/*init_flag = 1;*/ + + dim_ddbg_mod_save(eDI_DBG_MOD_RVE, channel, 0); + } +} + +/*para 1 not use*/ + +/* + * provider/receiver interface + */ + +/*************************/ +int di_ori_event_unreg(unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + pr_dbg("%s , is_bypass() %d trick_mode %d bypass_all %d\n", + __func__, + dim_is_bypass(NULL, channel), + trick_mode, + di_cfgx_get(channel, eDI_CFGX_BYPASS_ALL)); + /*dbg_ev("%s:unreg\n", __func__);*/ + dip_even_unreg_val(channel); /*new*/ + + ppre->vdin_source = false; + + dip_event_unreg_chst(channel); + +#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 + di_bypass_state_set(channel, true); +#ifdef RUN_DI_PROCESS_IN_IRQ + if (ppre->vdin_source) + dim_DI_Wr_reg_bits(VDIN_WR_CTRL, 0x3, 24, 3); +#endif + + dbg_ev("ch[%d]unreg end\n", channel); + return 0; +} + +int di_ori_event_reg(void *data, unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + struct vframe_receiver_s *preceiver; + + char *provider_name = (char *)data; + const char *receiver_name = NULL; + + dip_even_reg_init_val(channel); + if (de_devp->flags & DI_SUSPEND_FLAG) { + PR_ERR("reg event device hasn't resumed\n"); + return -1; + } + if (get_reg_flag(channel)) { + PR_ERR("no muti instance.\n"); + return -1; + } + dbg_ev("reg:%s\n", provider_name); + + di_bypass_state_set(channel, false); + + dip_event_reg_chst(channel); + + if (strncmp(provider_name, "vdin0", 4) == 0) + ppre->vdin_source = true; + else + ppre->vdin_source = false; + + /*ary: need use interface api*/ + /*receiver_name = vf_get_receiver_name(VFM_NAME);*/ + preceiver = vf_get_receiver(di_rev_name[channel]); + receiver_name = preceiver->name; + if (receiver_name) { + if (!strcmp(receiver_name, "amvideo")) { + ppost->run_early_proc_fun_flag = 0; + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support)) + ppost->run_early_proc_fun_flag = 1; + } else { + ppost->run_early_proc_fun_flag = 1; + pr_info("set run_early_proc_fun_flag to 1\n"); + } + } else { + pr_info("%s error receiver is null.\n", __func__); + } + + dbg_ev("ch[%d]:reg end\n", channel); + return 0; +} + +int di_ori_event_qurey_vdin2nr(unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + return ppre->vdin2nr; +} + +int di_ori_event_reset(unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct vframe_s **pvframe_in = get_vframe_in(channel); + int i; + ulong flags; + + /*block*/ + di_blocking = 1; + + /*dbg_ev("%s: VFRAME_EVENT_PROVIDER_RESET\n", __func__);*/ + if (dim_is_bypass(NULL, channel) || + di_bypass_state_get(channel) || + ppre->bypass_flag) { + pw_vf_notify_receiver(channel, + VFRAME_EVENT_PROVIDER_RESET, + NULL); + } + + spin_lock_irqsave(&plist_lock, flags); + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + if (pvframe_in[i]) + pr_dbg("DI:clear vframe_in[%d]\n", i); + + pvframe_in[i] = NULL; + } + spin_unlock_irqrestore(&plist_lock, flags); + di_blocking = 0; + + return 0; +} + +int di_ori_event_light_unreg(unsigned int channel) +{ + struct vframe_s **pvframe_in = get_vframe_in(channel); + int i; + ulong flags; + + di_blocking = 1; + + pr_dbg("%s: vf_notify_receiver ligth unreg\n", __func__); + + spin_lock_irqsave(&plist_lock, flags); + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + if (pvframe_in[i]) + pr_dbg("DI:clear vframe_in[%d]\n", i); + + pvframe_in[i] = NULL; + } + spin_unlock_irqrestore(&plist_lock, flags); + di_blocking = 0; + + return 0; +} + +int di_ori_event_light_unreg_revframe(unsigned int channel) +{ + struct vframe_s **pvframe_in = get_vframe_in(channel); + int i; + ulong flags; + + unsigned char vf_put_flag = 0; + + pr_info( + "%s:VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME\n", + __func__); +/* + * 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 (pvframe_in[i]) { + pw_vf_put(pvframe_in[i], channel); + pr_dbg("DI:clear vframe_in[%d]\n", i); + vf_put_flag = 1; + } + pvframe_in[i] = NULL; + } + if (vf_put_flag) + pw_vf_notify_provider(channel, + VFRAME_EVENT_RECEIVER_PUT, NULL); + + spin_unlock_irqrestore(&plist_lock, flags); + + return 0; +} + +int di_irq_ori_event_ready(unsigned int channel) +{ + return 0; +} + +int di_ori_event_ready(unsigned int channel) +{ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (ppre->bypass_flag) + pw_vf_notify_receiver(channel, + VFRAME_EVENT_PROVIDER_VFRAME_READY, + NULL); + + if (dip_chst_get(channel) == eDI_TOP_STATE_REG_STEP1) + task_send_cmd(LCMD1(eCMD_READY, channel)); + else + task_send_ready(); + + di_irq_ori_event_ready(channel); + return 0; +} + +int di_ori_event_qurey_state(unsigned int channel) +{ + /*int in_buf_num = 0;*/ + struct vframe_states states; + + if (recovery_flag) + return RECEIVER_INACTIVE; + + /*fix for ucode reset method be break by di.20151230*/ + di_vf_l_states(&states, channel); + if (states.buf_avail_num > 0) + return RECEIVER_ACTIVE; + + if (pw_vf_notify_receiver( + channel, + VFRAME_EVENT_PROVIDER_QUREY_STATE, + NULL) == RECEIVER_ACTIVE) + return RECEIVER_ACTIVE; + + return RECEIVER_INACTIVE; +} + +void di_ori_event_set_3D(int type, void *data, unsigned int channel) +{ +#ifdef DET3D + + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (type == VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE) { + int flag = (long)data; + + ppre->vframe_interleave_flag = flag; + } + +#endif +} + +/*************************/ + +/*recycle the buffer for keeping buffer*/ +static void recycle_keep_buffer(unsigned int channel) +{ + ulong irq_flag2 = 0; + int i = 0; + struct di_buf_s *keep_buf; + struct di_post_stru_s *ppost = get_post_stru(channel); + + keep_buf = ppost->keep_buf; + if (!IS_ERR_OR_NULL(keep_buf)) { + PR_ERR("%s:\n", __func__); + if (keep_buf->type == VFRAME_TYPE_POST) { + pr_dbg("%s recycle keep cur di_buf %d (", + __func__, keep_buf->index); + di_lock_irqfiq_save(irq_flag2); + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) { + if (keep_buf->di_buf_dup_p[i]) { + queue_in(channel, + keep_buf->di_buf_dup_p[i], + QUEUE_RECYCLE); + pr_dbg(" %d ", + keep_buf->di_buf_dup_p[i]->index); + } + } + di_que_in(channel, QUE_POST_FREE, keep_buf); + di_unlock_irqfiq_restore(irq_flag2); + pr_dbg(")\n"); + } + ppost->keep_buf = NULL; + } +} + +/************************************/ +/************************************/ +struct vframe_s *di_vf_l_get(unsigned int channel) +{ + vframe_t *vframe_ret = NULL; + struct di_buf_s *di_buf = NULL; +#ifdef DI_DEBUG_POST_BUF_FLOW + struct di_buf_s *nr_buf = NULL; +#endif + + ulong irq_flag2 = 0; + struct di_post_stru_s *ppost = get_post_stru(channel); + + dim_print("%s:ch[%d]\n", __func__, channel); + + if (!get_init_flag(channel) || + recovery_flag || + di_blocking || + !get_reg_flag(channel) || + dump_state_flag) { + dim_tr_ops.post_get2(1); + return NULL; + } + + /**************************/ + if (list_count(channel, QUEUE_DISPLAY) > 2) { + dim_tr_ops.post_get2(2); + return NULL; + } + /**************************/ + +#ifdef SUPPORT_START_FRAME_HOLD + if ((disp_frame_count == 0) && (dim_is_bypass(NULL, channel) == 0)) { + int ready_count = di_que_list_count(channel, QUE_POST_READY); + + if (ready_count > start_frame_hold_count) + goto get_vframe; + } else +#endif + if (!di_que_is_empty(channel, QUE_POST_READY)) { +#ifdef SUPPORT_START_FRAME_HOLD +get_vframe: +#endif + dim_log_buffer_state("ge_", channel); + di_lock_irqfiq_save(irq_flag2); + + di_buf = di_que_out_to_di_buf(channel, QUE_POST_READY); + if (dim_check_di_buf(di_buf, 21, channel)) { + di_unlock_irqfiq_restore(irq_flag2); + return NULL; + } + /* add it into display_list */ + queue_in(channel, di_buf, QUEUE_DISPLAY); + + di_unlock_irqfiq_restore(irq_flag2); + + if (di_buf) { + vframe_ret = di_buf->vframe; +#ifdef DI_DEBUG_POST_BUF_FLOW + nr_buf = di_buf->di_buf_dup_p[1]; + if (dimp_get(eDI_MP_post_wr_en) && + dimp_get(eDI_MP_post_wr_support) && + (di_buf->process_fun_index != PROCESS_FUN_NULL)) { + #ifdef CONFIG_AMLOGIC_MEDIA_MULTI_DEC + vframe_ret->canvas0_config[0].phy_addr = + di_buf->nr_adr; + vframe_ret->canvas0_config[0].width = + di_buf->canvas_width[NR_CANVAS], + vframe_ret->canvas0_config[0].height = + di_buf->canvas_height; + vframe_ret->canvas0_config[0].block_mode = 0; + vframe_ret->plane_num = 1; + vframe_ret->canvas0Addr = -1; + vframe_ret->canvas1Addr = -1; + if (di_mp_uit_get(eDI_MP_show_nrwr)) { + vframe_ret->canvas0_config[0].phy_addr = + nr_buf->nr_adr; + vframe_ret->canvas0_config[0].width = + nr_buf->canvas_width[NR_CANVAS]; + vframe_ret->canvas0_config[0].height = + nr_buf->canvas_height; + } + #else + config_canvas_idx(di_buf, di_wr_idx, -1); + vframe_ret->canvas0Addr = di_buf->nr_canvas_idx; + vframe_ret->canvas1Addr = di_buf->nr_canvas_idx; + if (di_mp_uit_get(eDI_MP_show_nrwr)) { + config_canvas_idx(nr_buf, + di_wr_idx, -1); + vframe_ret->canvas0Addr = di_wr_idx; + vframe_ret->canvas1Addr = di_wr_idx; + } + #endif + vframe_ret->early_process_fun = dim_do_post_wr_fun; + vframe_ret->process_fun = NULL; + } +#endif + di_buf->seq = disp_frame_count; + atomic_set(&di_buf->di_cnt, 1); + } + disp_frame_count++; + + dim_log_buffer_state("get", channel); + } + if (vframe_ret) { + dim_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)); + didbg_vframe_out_save(vframe_ret); + + dim_tr_ops.post_get(vframe_ret->omx_index); + } else { + dim_tr_ops.post_get2(3); + } + + if (!dimp_get(eDI_MP_post_wr_en) && + ppost->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); + } + return vframe_ret; +} + +void di_vf_l_put(struct vframe_s *vf, unsigned char channel) +{ + struct di_buf_s *di_buf = NULL; + ulong irq_flag2 = 0; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_post_stru_s *ppost = get_post_stru(channel); + + dim_print("%s:ch[%d]\n", __func__, channel); + + if (ppre->bypass_flag) { + pw_vf_put(vf, channel); + pw_vf_notify_provider(channel, + VFRAME_EVENT_RECEIVER_PUT, NULL); + if (!IS_ERR_OR_NULL(ppost->keep_buf)) + recycle_keep_buffer(channel); + return; + } +/* struct di_buf_s *p = NULL; */ +/* int itmp = 0; */ + if (!get_init_flag(channel) || + recovery_flag || + IS_ERR_OR_NULL(vf)) { + PR_ERR("%s: 0x%p\n", __func__, vf); + return; + } + if (di_blocking) + return; + dim_log_buffer_state("pu_", channel); + di_buf = (struct di_buf_s *)vf->private_data; + if (IS_ERR_OR_NULL(di_buf)) { + pw_vf_put(vf, channel); + pw_vf_notify_provider(channel, + VFRAME_EVENT_RECEIVER_PUT, NULL); + PR_ERR("%s: get vframe %p without di buf\n", + __func__, vf); + return; + } +#if 0 + if (ppost->keep_buf == di_buf) { + pr_info("[DI]recycle buffer %d, get cnt %d.\n", + di_buf->index, disp_frame_count); + recycle_keep_buffer(channel); + } +#else + +#endif + + if (di_buf->type == VFRAME_TYPE_POST + ) { +#if 0 + dim_print("%s:put:%d\n", __func__, di_buf->index); + + di_lock_irqfiq_save(irq_flag2); + + if (is_in_queue(channel, di_buf, QUEUE_DISPLAY)) { + if (!atomic_dec_and_test(&di_buf->di_cnt)) + dim_print("%s,di_cnt > 0\n", __func__); + dim_print("%s:put:%d\n", __func__, di_buf->index); + recycle_vframe_type_post(di_buf, channel); + } else { + dim_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); +#ifdef DI_BUFFER_DEBUG + recycle_vframe_type_post_print(di_buf, __func__, __LINE__); +#endif +#else + pw_queue_in(channel, QUE_POST_BACK, di_buf->index); +#endif + } else { + di_lock_irqfiq_save(irq_flag2); + queue_in(channel, di_buf, QUEUE_RECYCLE); + di_unlock_irqfiq_restore(irq_flag2); + + dim_print("%s: %s[%d] =>recycle_list\n", __func__, + vframe_type_name[di_buf->type], di_buf->index); + } + + task_send_ready(); +} + +void dim_recycle_post_back(unsigned int channel) +{ + struct di_buf_s *di_buf = NULL; + unsigned int post_buf_index; + struct di_buf_s *pbuf_post = get_buf_post(channel); + ulong irq_flag2 = 0; + + struct di_post_stru_s *ppost = get_post_stru(channel); + + if (pw_queue_empty(channel, QUE_POST_BACK)) + return; + + while (pw_queue_out(channel, QUE_POST_BACK, &post_buf_index)) { + /*pr_info("dp2:%d\n", post_buf_index);*/ + if (post_buf_index >= MAX_POST_BUF_NUM) { + PR_ERR("%s:index is overlfow[%d]\n", + __func__, post_buf_index); + break; + } + dim_print("di_back:%d\n", post_buf_index); + di_lock_irqfiq_save(irq_flag2); /**/ + + di_buf = &pbuf_post[post_buf_index]; + if (!atomic_dec_and_test(&di_buf->di_cnt)) + PR_ERR("%s,di_cnt > 0\n", __func__); + recycle_vframe_type_post(di_buf, channel); + di_unlock_irqfiq_restore(irq_flag2); + } + /*back keep_buf:*/ + if (ppost->keep_buf_post) { + PR_INF("ch[%d]:%s:%d\n", + channel, + __func__, + ppost->keep_buf_post->index); + di_lock_irqfiq_save(irq_flag2); /**/ + di_que_in(channel, QUE_POST_FREE, ppost->keep_buf_post); + di_unlock_irqfiq_restore(irq_flag2); + ppost->keep_buf_post = NULL; + } +} + +struct vframe_s *di_vf_l_peek(unsigned int channel) +{ + struct vframe_s *vframe_ret = NULL; + struct di_buf_s *di_buf = NULL; + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + /*dim_print("%s:ch[%d]\n",__func__, channel);*/ + + di_sum_inc(channel, eDI_SUM_O_PEEK_CNT); + if (ppre->bypass_flag) { + dim_tr_ops.post_peek(0); + return pw_vf_peek(channel); + } + if (!get_init_flag(channel) || + recovery_flag || + di_blocking || + !get_reg_flag(channel) || + dump_state_flag) { + dim_tr_ops.post_peek(1); + return NULL; + } + + /**************************/ + if (list_count(channel, QUEUE_DISPLAY) > DI_POST_GET_LIMIT) { + dim_tr_ops.post_peek(2); + return NULL; + } + /**************************/ + dim_log_buffer_state("pek", channel); + +#ifdef SUPPORT_START_FRAME_HOLD + if ((disp_frame_count == 0) && (dim_is_bypass(NULL, channel) == 0)) { + int ready_count = di_que_list_count(channel, QUE_POST_READY); + + if (ready_count > start_frame_hold_count) { + di_buf = di_que_peek(channel, QUE_POST_READY); + if (di_buf) + vframe_ret = di_buf->vframe; + } + } else +#endif + { + if (!di_que_is_empty(channel, QUE_POST_READY)) { + di_buf = di_que_peek(channel, QUE_POST_READY); + if (di_buf) + vframe_ret = di_buf->vframe; + } + } +#ifdef DI_BUFFER_DEBUG + if (vframe_ret) + dim_print("%s: %s[%d]:%x\n", __func__, + vframe_type_name[di_buf->type], + di_buf->index, vframe_ret); +#endif + if (vframe_ret) + dim_tr_ops.post_peek(9); + else + dim_tr_ops.post_peek(4); + return vframe_ret; +} + +int di_vf_l_states(struct vframe_states *states, unsigned int channel) +{ + struct di_mm_s *mm = dim_mm_get(); + + /*pr_info("%s: ch[%d]\n", __func__, channel);*/ + if (!states) + return -1; + states->vf_pool_size = mm->sts.num_local; + states->buf_free_num = list_count(channel, QUEUE_LOCAL_FREE); + + states->buf_avail_num = di_que_list_count(channel, QUE_POST_READY); + states->buf_recycle_num = list_count(channel, QUEUE_RECYCLE); + if (dimp_get(eDI_MP_di_dbg_mask) & 0x1) { + di_pr_info("di-pre-ready-num:%d\n", + /*new que list_count(channel, QUEUE_PRE_READY));*/ + di_que_list_count(channel, QUE_PRE_READY)); + di_pr_info("di-display-num:%d\n", + list_count(channel, QUEUE_DISPLAY)); + } + return 0; +} + +/**********************************************/ + +/***************************** + * di driver file_operations + * + ******************************/ +#if 0 /*move to di_sys.c*/ +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 */ + file->private_data = NULL; + return 0; +} + +#endif /*move to di_sys.c*/ + +static struct di_pq_parm_s *di_pq_parm_create(struct am_pq_parm_s *pq_parm_p) +{ + struct di_pq_parm_s *pq_ptr = NULL; + struct am_reg_s *am_reg_p = NULL; + size_t mem_size = 0; + + pq_ptr = vzalloc(sizeof(*pq_ptr)); + mem_size = sizeof(struct am_pq_parm_s); + memcpy(&pq_ptr->pq_parm, pq_parm_p, mem_size); + mem_size = sizeof(struct am_reg_s) * pq_parm_p->table_len; + am_reg_p = vzalloc(mem_size); + if (!am_reg_p) { + vfree(pq_ptr); + PR_ERR("alloc pq table memory errors\n"); + return NULL; + } + pq_ptr->regs = am_reg_p; + + return pq_ptr; +} + +static void di_pq_parm_destroy(struct di_pq_parm_s *pq_ptr) +{ + if (!pq_ptr) { + PR_ERR("%s pq parm pointer null.\n", __func__); + return; + } + vfree(pq_ptr->regs); + vfree(pq_ptr); +} + +/*move from ioctrl*/ +long dim_pq_load_io(unsigned long arg) +{ + long ret = 0, tab_flag = 0; + di_dev_t *di_devp; + void __user *argp = (void __user *)arg; + size_t mm_size = 0; + struct am_pq_parm_s tmp_pq_s = {0}; + struct di_pq_parm_s *di_pq_ptr = NULL; + struct di_dev_s *de_devp = get_dim_de_devp(); + unsigned int channel = 0; /*fix to channel 0*/ + + di_devp = de_devp; + + mm_size = sizeof(struct am_pq_parm_s); + if (copy_from_user(&tmp_pq_s, argp, mm_size)) { + PR_ERR("set pq parm errors\n"); + return -EFAULT; + } + if (tmp_pq_s.table_len >= TABLE_LEN_MAX) { + PR_ERR("load 0x%x wrong pq table_len.\n", + tmp_pq_s.table_len); + return -EFAULT; + } + tab_flag = TABLE_NAME_DI | TABLE_NAME_NR | TABLE_NAME_MCDI | + TABLE_NAME_DEBLOCK | TABLE_NAME_DEMOSQUITO; + if (tmp_pq_s.table_name & tab_flag) { + pr_info("[DI] load 0x%x pq table len %u %s.\n", + tmp_pq_s.table_name, tmp_pq_s.table_len, + get_init_flag(channel) ? "directly" : "later"); + } else { + PR_ERR("load 0x%x wrong pq table.\n", + tmp_pq_s.table_name); + return -EFAULT; + } + di_pq_ptr = di_pq_parm_create(&tmp_pq_s); + if (!di_pq_ptr) { + PR_ERR("allocat pq parm struct error.\n"); + return -EFAULT; + } + argp = (void __user *)tmp_pq_s.table_ptr; + mm_size = tmp_pq_s.table_len * sizeof(struct am_reg_s); + if (copy_from_user(di_pq_ptr->regs, argp, mm_size)) { + PR_ERR("user copy pq table errors\n"); + return -EFAULT; + } + if (get_init_flag(channel)) { + dimh_load_regs(di_pq_ptr); + di_pq_parm_destroy(di_pq_ptr); + + return ret; + } + if (atomic_read(&de_devp->pq_flag) == 0) { + atomic_set(&de_devp->pq_flag, 1); + if (di_devp->flags & DI_LOAD_REG_FLAG) { + struct di_pq_parm_s *pos = NULL, *tmp = NULL; + + list_for_each_entry_safe(pos, tmp, + &di_devp->pq_table_list, list) { + if (di_pq_ptr->pq_parm.table_name == + pos->pq_parm.table_name) { + pr_info("[DI] remove 0x%x table.\n", + pos->pq_parm.table_name); + list_del(&pos->list); + di_pq_parm_destroy(pos); + } + } + } + list_add_tail(&di_pq_ptr->list, + &di_devp->pq_table_list); + di_devp->flags |= DI_LOAD_REG_FLAG; + atomic_set(&de_devp->pq_flag, 0); + } else { + PR_ERR("please retry table name 0x%x.\n", + di_pq_ptr->pq_parm.table_name); + di_pq_parm_destroy(di_pq_ptr); + ret = -EFAULT; + } + + return ret; +} + +#if 0 /*#ifdef CONFIG_AMLOGIC_MEDIA_RDMA*/ +unsigned int dim_RDMA_RD_BITS(unsigned int adr, unsigned int start, + unsigned int len) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (de_devp->rdma_handle && di_pre_rdma_enable) + return rdma_read_reg(de_devp->rdma_handle, adr) & + (((1 << len) - 1) << start); + else + return Rd_reg_bits(adr, start, len); +} + +unsigned int dim_RDMA_WR(unsigned int adr, unsigned int val) +{ + unsigned int channel = get_current_channel(); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (is_need_stop_reg(adr)) + return 0; + + if (de_devp->rdma_handle > 0 && di_pre_rdma_enable) { + if (ppre->field_count_for_cont < 1) + dim_DI_Wr(adr, val); + else + rdma_write_reg(de_devp->rdma_handle, adr, val); + return 0; + } + + dim_DI_Wr(adr, val); + return 1; +} + +unsigned int dim_RDMA_RD(unsigned int adr) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + + 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 dim_RDMA_WR_BITS(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len) +{ + unsigned int channel = get_current_channel(); + struct di_pre_stru_s *ppre = get_pre_stru(channel); + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (is_need_stop_reg(adr)) + return 0; + + if (de_devp->rdma_handle > 0 && di_pre_rdma_enable) { + if (ppre->field_count_for_cont < 1) + dim_DI_Wr_reg_bits(adr, val, start, len); + else + rdma_write_reg_bits(de_devp->rdma_handle, + adr, val, start, len); + return 0; + } + dim_DI_Wr_reg_bits(adr, val, start, len); + return 1; +} +#else +unsigned int dim_RDMA_RD_BITS(unsigned int adr, unsigned int start, + unsigned int len) +{ + return Rd_reg_bits(adr, start, len); +} + +unsigned int dim_RDMA_WR(unsigned int adr, unsigned int val) +{ + dim_DI_Wr(adr, val); + return 1; +} + +unsigned int dim_RDMA_RD(unsigned int adr) +{ + return Rd(adr); +} + +unsigned int dim_RDMA_WR_BITS(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len) +{ + dim_DI_Wr_reg_bits(adr, val, start, len); + return 1; +} +#endif + +void dim_set_di_flag(void) +{ + if (is_meson_txl_cpu() || + is_meson_txlx_cpu() || + is_meson_gxlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || + is_meson_sm1_cpu()) { + dimp_set(eDI_MP_mcpre_en, 1); + mc_mem_alloc = true; + dimp_set(eDI_MP_pulldown_enable, 0); + di_pre_rdma_enable = false; + /* + * txlx atsc 1080i ei only will cause flicker + * when full to small win in home screen + */ + + dimp_set(eDI_MP_di_vscale_skip_enable, + (is_meson_txlx_cpu() || + is_meson_txhd_cpu()) ? 12 : 4); + /*use_2_interlace_buff = is_meson_gxlx_cpu()?0:1;*/ + dimp_set(eDI_MP_use_2_interlace_buff, + is_meson_gxlx_cpu() ? 0 : 1); + if (is_meson_txl_cpu() || + is_meson_txlx_cpu() || + is_meson_gxlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || + is_meson_sm1_cpu()) { + dimp_set(eDI_MP_full_422_pack, 1); + } + + if (dimp_get(eDI_MP_nr10bit_support)) { + dimp_set(eDI_MP_di_force_bit_mode, 10); + } else { + dimp_set(eDI_MP_di_force_bit_mode, 8); + dimp_set(eDI_MP_full_422_pack, 0); + } + + dimp_set(eDI_MP_post_hold_line, + (is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu() || + is_meson_sm1_cpu()) ? 10 : 17); + } else { + /*post_hold_line = 8;*/ /*2019-01-10: from VLSI feijun*/ + dimp_set(eDI_MP_post_hold_line, 8); + dimp_set(eDI_MP_mcpre_en, 0); + dimp_set(eDI_MP_pulldown_enable, 0); + di_pre_rdma_enable = false; + dimp_set(eDI_MP_di_vscale_skip_enable, 4); + dimp_set(eDI_MP_use_2_interlace_buff, 0); + dimp_set(eDI_MP_di_force_bit_mode, 8); + } + /*if (is_meson_tl1_cpu() || is_meson_tm2_cpu())*/ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dimp_set(eDI_MP_pulldown_enable, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + intr_mode = 3; + if (di_pre_rdma_enable) { + pldn_dly = 1; + pldn_dly1 = 1; + } else { + pldn_dly = 2; + pldn_dly1 = 2; + } + + get_ops_mtn()->mtn_int_combing_glbmot(); +} + +#if 0 /*move to di_sys.c*/ +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); +#endif + +void dim_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev) +{ + int ret = 0; + unsigned int tmp_clk[2] = {0, 0}; + struct clk *vpu_clk = NULL; + struct clk *clkb_tmp_comp = NULL; + + vpu_clk = clk_get(dev, "vpu_mux"); + if (IS_ERR(vpu_clk)) + PR_ERR("%s: get clk vpu error.\n", __func__); + else + clk_prepare_enable(vpu_clk); + + ret = of_property_read_u32_array(dev->of_node, "clock-range", + tmp_clk, 2); + if (ret) { + pdev->clkb_min_rate = 250000000; + pdev->clkb_max_rate = 500000000; + } else { + pdev->clkb_min_rate = tmp_clk[0] * 1000000; + pdev->clkb_max_rate = tmp_clk[1] * 1000000; + } + pr_info("DI: vpu clkb <%lu, %lu>\n", pdev->clkb_min_rate, + pdev->clkb_max_rate); + #ifdef CLK_TREE_SUPPORT + pdev->vpu_clkb = clk_get(dev, "vpu_clkb_composite"); + if (is_meson_tl1_cpu()) { + clkb_tmp_comp = clk_get(dev, "vpu_clkb_tmp_composite"); + if (IS_ERR(clkb_tmp_comp)) { + PR_ERR("clkb_tmp_comp error\n"); + } else { + /*ary: this make clk from 500 to 666?*/ + if (!IS_ERR(vpu_clk)) + clk_set_parent(clkb_tmp_comp, vpu_clk); + } + } + + if (IS_ERR(pdev->vpu_clkb)) { + PR_ERR("%s: get vpu clkb gate error.\n", __func__); + } else { + clk_set_rate(pdev->vpu_clkb, pdev->clkb_min_rate); + pr_info("get clkb rate:%ld\n", clk_get_rate(pdev->vpu_clkb)); + } + + #endif +} + +module_param_named(invert_top_bot, invert_top_bot, int, 0664); + +#ifdef SUPPORT_START_FRAME_HOLD +module_param_named(start_frame_hold_count, start_frame_hold_count, int, 0664); +#endif + +#ifdef DET3D + +MODULE_PARM_DESC(det3d_mode, "\n det3d_mode\n"); +module_param(det3d_mode, uint, 0664); +#endif + +module_param_array(di_stop_reg_addr, uint, &num_di_stop_reg_addr, + 0664); + +module_param_named(overturn, overturn, bool, 0664); + +#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 +#ifdef SUPPORT_MPEG_TO_VDIN +module_param_named(mpeg2vdin_en, mpeg2vdin_en, int, 0664); +module_param_named(mpeg2vdin_flag, mpeg2vdin_flag, int, 0664); +#endif +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(pldn_dly1, pldn_dly1, uint, 0644); +module_param_named(di_reg_unreg_cnt, di_reg_unreg_cnt, int, 0664); +module_param_named(bypass_pre, bypass_pre, int, 0664); +module_param_named(frame_count, frame_count, int, 0664); +#endif + +int dim_seq_file_module_para_di(struct seq_file *seq) +{ + seq_puts(seq, "di---------------\n"); + +#ifdef DET3D + seq_printf(seq, "%-15s:%d\n", "det3d_frame_cnt", det3d_frame_cnt); +#endif + +#ifdef SUPPORT_START_FRAME_HOLD + seq_printf(seq, "%-15s:%d\n", "start_frame_hold_count", + start_frame_hold_count); +#endif + seq_printf(seq, "%-15s:%ld\n", "same_field_top_count", + same_field_top_count); + seq_printf(seq, "%-15s:%ld\n", "same_field_bot_count", + same_field_bot_count); + + seq_printf(seq, "%-15s:%d\n", "overturn", overturn); + +#ifdef DEBUG_SUPPORT +#ifdef RUN_DI_PROCESS_IN_IRQ + seq_printf(seq, "%-15s:%d\n", "input2pre", input2pre); + seq_printf(seq, "%-15s:%d\n", "input2pre_buf_miss_count", + input2pre_buf_miss_count); + seq_printf(seq, "%-15s:%d\n", "input2pre_proc_miss_count", + input2pre_proc_miss_count); + seq_printf(seq, "%-15s:%d\n", "input2pre_miss_policy", + input2pre_miss_policy); + seq_printf(seq, "%-15s:%d\n", "input2pre_throw_count", + input2pre_throw_count); +#endif +#ifdef SUPPORT_MPEG_TO_VDIN + + seq_printf(seq, "%-15s:%d\n", "mpeg2vdin_en", mpeg2vdin_en); + seq_printf(seq, "%-15s:%d\n", "mpeg2vdin_flag", mpeg2vdin_flag); +#endif + seq_printf(seq, "%-15s:%d\n", "di_pre_rdma_enable", + di_pre_rdma_enable); + seq_printf(seq, "%-15s:%d\n", "pldn_dly", pldn_dly); + seq_printf(seq, "%-15s:%d\n", "pldn_dly1", pldn_dly1); + seq_printf(seq, "%-15s:%d\n", "di_reg_unreg_cnt", di_reg_unreg_cnt); + seq_printf(seq, "%-15s:%d\n", "bypass_pre", bypass_pre); + seq_printf(seq, "%-15s:%d\n", "frame_count", frame_count); +#endif +/******************************/ + +#ifdef DET3D + seq_printf(seq, "%-15s:%d\n", "det3d_mode", det3d_mode); +#endif + return 0; +} + +#if 0 /*move to di_sys.c*/ +MODULE_DESCRIPTION("AMLOGIC DEINTERLACE driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("4.0.0"); +#endif diff --git a/drivers/amlogic/media/di_multi/deinterlace.h b/drivers/amlogic/media/di_multi/deinterlace.h new file mode 100644 index 0000000..8a1cac0 --- /dev/null +++ b/drivers/amlogic/media/di_multi/deinterlace.h @@ -0,0 +1,656 @@ +/* + * drivers/amlogic/media/di_multi/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 "../di_local/di_local.h" +#include +#include +#include "deinterlace_hw.h" +#include "../deinterlace/di_pqa.h" + +/*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_PROVERDER_REG 'R' + +#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 + +#define USED_LOCAL_BUF_MAX 3 +#define BYPASS_GET_MAX_BUF_NUM 4 + +/* buffer management related */ +#define MAX_IN_BUF_NUM (4) +#define MAX_LOCAL_BUF_NUM (7) +#define MAX_POST_BUF_NUM (7) /*(5)*/ /* 16 */ + +#define VFRAME_TYPE_IN 1 +#define VFRAME_TYPE_LOCAL 2 +#define VFRAME_TYPE_POST 3 +#define VFRAME_TYPE_NUM 3 + +#define DI_POST_GET_LIMIT 4 +#define DI_PRE_READY_LIMIT 4 +/*vframe define*/ +#define vframe_t struct vframe_s + +#define is_from_vdin(vframe) ((vframe)->type & VIDTYPE_VIU_422) + +/* canvas defination */ +#define DI_USE_FIXED_CANVAS_IDX +/*#define DET3D */ +#undef SUPPORT_MPEG_TO_VDIN +#define CLK_TREE_SUPPORT +#ifndef CONFIG_AMLOGIC_MEDIA_RDMA +#ifndef VSYNC_WR_MPEG_REG +#define VSYNC_WR_MPEG_REG(adr, val) aml_write_vcbus(adr, val) +#define VSYNC_WR_MPEG_REG_BITS(adr, val, start, len) \ + aml_vcbus_update_bits((adr), \ + ((1 << (len)) - 1) << (start), (val) << (start)) + +#define VSYNC_RD_MPEG_REG(adr) aml_read_vcbus(adr) +#endif +#endif + +#define IS_VDIN_SRC(src) ( \ + ((src) == VFRAME_SOURCE_TYPE_TUNER) || \ + ((src) == VFRAME_SOURCE_TYPE_CVBS) || \ + ((src) == VFRAME_SOURCE_TYPE_COMP) || \ + ((src) == VFRAME_SOURCE_TYPE_HDMI)) + +#define IS_I_SRC(vftype) ((vftype) & VIDTYPE_INTERLACE_BOTTOM) + +#define IS_COMP_MODE(vftype) ((vftype) & VIDTYPE_COMPRESS) + +enum process_fun_index_e { + PROCESS_FUN_NULL = 0, + PROCESS_FUN_DI, + PROCESS_FUN_PD, + PROCESS_FUN_PROG, + PROCESS_FUN_BOB +}; + +#define process_fun_index_t enum process_fun_index_e + +enum canvas_idx_e { + NR_CANVAS, + MTN_CANVAS, + MV_CANVAS, +}; + +#define pulldown_mode_t enum pulldown_mode_e +struct di_buf_s { + struct vframe_s *vframe; + int index; /* index in vframe_in_dup[] or vframe_in[], + * only for type of VFRAME_TYPE_IN + */ + int post_proc_flag; /* 0,no post di; 1, normal post di; + * 2, edge only; 3, dummy + */ + int new_format_flag; + int type; + int throw_flag; + int invert_top_bot_flag; + int seq; + int pre_ref_count; /* none zero, is used by mem_mif, + * chan2_mif, or wr_buf + */ + int post_ref_count; /* none zero, is used by post process */ + int queue_index; + /*below for type of VFRAME_TYPE_LOCAL */ + unsigned long nr_adr; + int nr_canvas_idx; + unsigned long mtn_adr; + int mtn_canvas_idx; + unsigned long cnt_adr; + int cnt_canvas_idx; + unsigned long mcinfo_adr; + int mcinfo_canvas_idx; + unsigned long mcvec_adr; + int mcvec_canvas_idx; + struct mcinfo_pre_s { + unsigned int highvertfrqflg; + unsigned int motionparadoxflg; + unsigned int regs[26];/* reg 0x2fb0~0x2fc9 */ + } curr_field_mcinfo; + /* blend window */ + struct pulldown_detected_s + pd_config; + /* tff bff check result bit[1:0]*/ + unsigned int privated; + unsigned int canvas_config_flag; + /* 0,configed; 1,config type 1 (prog); + * 2, config type 2 (interlace) + */ + unsigned int canvas_height; + unsigned int canvas_height_mc; /*ary add for mc h is diff*/ + unsigned int canvas_width[3];/* nr/mtn/mv */ + process_fun_index_t process_fun_index; + int early_process_fun_index; + int left_right;/*1,left eye; 0,right eye in field alternative*/ + /*below for type of VFRAME_TYPE_POST*/ + struct di_buf_s *di_buf[2]; + struct di_buf_s *di_buf_dup_p[5]; + /* 0~4: n-2, n-1, n, n+1, n+2; n is the field to display*/ + /*0: n-2*/ + /*1: n-1*/ + /*2: n*/ + /*3: n+1*/ + /*4: n+2*/ + struct di_buf_s *di_wr_linked_buf; + /* debug for di-vf-get/put + * 1: after get + * 0: after put + */ + atomic_t di_cnt; + struct page *pages; + /*ary add */ + unsigned int channel; + unsigned int width_bk; /*move from ppre*/ +}; + +#define RDMA_DET3D_IRQ 0x20 +/* vdin0 rdma irq */ +#define RDMA_DEINT_IRQ 0x2 +#define RDMA_TABLE_SIZE ((PAGE_SIZE) << 1) + +#define MAX_CANVAS_WIDTH 1920 +#define MAX_CANVAS_HEIGHT 1088 + +/* #define DI_BUFFER_DEBUG */ + +#define DI_LOG_MTNINFO 0x02 +#define DI_LOG_PULLDOWN 0x10 +#define DI_LOG_BUFFER_STATE 0x20 +#define DI_LOG_TIMESTAMP 0x100 +#define DI_LOG_PRECISE_TIMESTAMP 0x200 +#define DI_LOG_QUEUE 0x40 +#define DI_LOG_VFRAME 0x80 + +#if 0 +#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 +#else +#define QUEUE_LOCAL_FREE 0 +#define QUEUE_RECYCLE 1 /* 5 */ +#define QUEUE_DISPLAY 2 /* 6 */ +#define QUEUE_TMP 3 /* 7 */ +#define QUEUE_POST_DOING 4 /* 8 */ + +#define QUEUE_IN_FREE 5 /* 1 */ +#define QUEUE_PRE_READY 6 /* 2 */ +#define QUEUE_POST_FREE 7 /* 3 */ +#define QUEUE_POST_READY 8 /* 4 QUE_POST_READY */ + +/*new use this for put back control*/ +#define QUEUE_POST_PUT_BACK (9) + +#define QUEUE_NUM 5 /* 9 */ +#define QUEUE_NEW_THD_MIN (QUEUE_IN_FREE - 1) +#define QUEUE_NEW_THD_MAX (QUEUE_POST_READY + 1) + +#endif + +#define queue_t struct queue_s + +#define VFM_NAME "deinterlace" + +#ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA +void enable_rdma(int enable_flag); +int VSYNC_WR_MPEG_REG(u32 adr, u32 val); +int VSYNC_WR_MPEG_REG_BITS(u32 adr, u32 val, u32 start, u32 len); +u32 VSYNC_RD_MPEG_REG(u32 adr); +bool is_vsync_rdma_enable(void); +#else +#ifndef VSYNC_WR_MPEG_REG +#define VSYNC_WR_MPEG_REG(adr, val) aml_write_vcbus(adr, val) +#define VSYNC_WR_MPEG_REG_BITS(adr, val, start, len) \ + aml_vcbus_update_bits((adr), \ + ((1 << (len)) - 1) << (start), (val) << (start)) + +#define VSYNC_RD_MPEG_REG(adr) aml_read_vcbus(adr) +#endif +#endif + +#define DI_COUNT 1 +#define DI_MAP_FLAG 0x1 +#define DI_SUSPEND_FLAG 0x2 +#define DI_LOAD_REG_FLAG 0x4 +#define DI_VPU_CLKB_SET 0x8 + +struct di_dev_s { + dev_t devt; + struct cdev cdev; /* The cdev structure */ + struct device *dev; + struct platform_device *pdev; + dev_t devno; + struct class *pclss; + + bool sema_flg; /*di_sema_init_flag*/ + + struct task_struct *task; + struct clk *vpu_clkb; + unsigned long clkb_max_rate; + unsigned long clkb_min_rate; + struct list_head pq_table_list; + atomic_t pq_flag; + unsigned char di_event; + unsigned int pre_irq; + unsigned int post_irq; + unsigned int flags; + unsigned long jiffy; + unsigned long mem_start; + unsigned int mem_size; + bool mem_flg; /*ary add for make sure mem is ok*/ + unsigned int buffer_size; + unsigned int post_buffer_size; + unsigned int buf_num_avail; + int rdma_handle; + /* is support nr10bit */ + unsigned int nr10bit_support; + /* is DI support post wr to mem for OMX */ + unsigned int post_wr_support; + unsigned int nrds_enable; + unsigned int pps_enable; + unsigned int h_sc_down_en;/*sm1, tm2 ...*/ + /*struct mutex cma_mutex;*/ + unsigned int flag_cma; + struct page *total_pages; + struct dentry *dbg_root; /*dbg_fs*/ + /***************************/ + /*struct di_data_l_s data_l;*/ + void *data_l; + +}; + +struct di_pre_stru_s { +/* pre input */ + struct DI_MIF_s di_inp_mif; + struct DI_MIF_s di_mem_mif; + struct DI_MIF_s di_chan2_mif; + struct di_buf_s *di_inp_buf; + struct di_buf_s *di_post_inp_buf; + struct di_buf_s *di_inp_buf_next; + /* p_asi_next: ary:add for p */ + struct di_buf_s *p_asi_next; + struct di_buf_s *di_mem_buf_dup_p; + struct di_buf_s *di_chan2_buf_dup_p; +/* pre output */ + struct DI_SIM_MIF_s di_nrwr_mif; + struct DI_SIM_MIF_s di_mtnwr_mif; + struct di_buf_s *di_wr_buf; + struct di_buf_s *di_post_wr_buf; + struct DI_SIM_MIF_s di_contp2rd_mif; + struct DI_SIM_MIF_s di_contprd_mif; + struct DI_SIM_MIF_s di_contwr_mif; + int field_count_for_cont; +/* + * 0 (f0,null,f0)->nr0, + * 1 (f1,nr0,f1)->nr1_cnt, + * 2 (f2,nr1_cnt,nr0)->nr2_cnt + * 3 (f3,nr2_cnt,nr1_cnt)->nr3_cnt + */ + 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_process_flag; /* flag when dim_pre_de_process done */ + int pre_de_clear_flag; + /* flag is set when VFRAME_EVENT_PROVIDER_UNREG*/ + int unreg_req_flag_cnt; + + int reg_req_flag_cnt; + 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; +/* input size change flag, 1: need reconfig pre/nr/dnr size */ +/* 0: not need config pre/nr/dnr size*/ + bool input_size_change_flag; +/* true: bypass di all logic, false: not bypass */ + bool bypass_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 + */ +/* ary: loacal play p mode is 0 + * local play i mode is 0 + */ + + unsigned char buf_alloc_mode; +/* alloc di buf as p or i;0: alloc buf as i; + * 1: alloc buf as p; + */ + unsigned char madi_enable; + unsigned char mcdi_enable; + unsigned int pps_dstw; /*no use ?*/ + unsigned int pps_dsth; /*no use ?*/ + int left_right;/*1,left eye; 0,right eye in field alternative*/ +/*input2pre*/ + int bypass_start_count; +/* need discard some vframe when input2pre => bypass */ + unsigned char 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; + unsigned int width_bk; +#ifdef DET3D + int vframe_interleave_flag; +#endif +/**/ + int pre_de_irq_timeout_count; + int pre_throw_flag; + int bad_frame_throw_count; +/*for static pic*/ + int static_frame_count; + bool force_interlace; + bool bypass_pre; + bool invert_flag; + bool vdin_source; + int nr_size; + int count_size; + int mcinfo_size; + int mv_size; + int mtn_size; + + int cma_release_req; + /* for performance debug */ + unsigned long irq_time[2]; + /* combing adaptive */ + struct combing_status_s *mtn_status; +}; + +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; + /*post doing buf and write buf to post ready*/ + struct di_buf_s *cur_post_buf; + struct di_buf_s *keep_buf; + struct di_buf_s *keep_buf_post; /*ary add for keep post buf*/ + int update_post_reg_flag; + 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; + unsigned int post_peek_underflow; + unsigned int di_post_process_cnt; + unsigned int check_recycle_buf_cnt;/*cp to di_hpre_s*/ + /* performance debug */ + unsigned int post_wr_cnt; + unsigned long irq_time; + + /*frame cnt*/ + unsigned int frame_cnt; /*cnt for post process*/ +}; + +#define MAX_QUEUE_POOL_SIZE 256 +struct queue_s { + unsigned int num; + unsigned int in_idx; + unsigned int out_idx; + unsigned int type; +/* 0, first in first out; + * 1, general;2, fix position for di buf + */ + unsigned int pool[MAX_QUEUE_POOL_SIZE]; +}; + +struct di_buf_pool_s { + struct di_buf_s *di_buf_ptr; + unsigned int size; +}; + +struct dim_mm_s { + struct page *ppage; + unsigned long addr; +}; + +bool dim_mm_alloc(int cma_mode, size_t count, struct dim_mm_s *o); +bool dim_mm_release(int cma_mode, + struct page *pages, + int count, + unsigned long addr); + +unsigned char dim_is_bypass(vframe_t *vf_in, unsigned int channel); +bool dim_bypass_first_frame(unsigned int ch); + +int di_cnt_buf(int width, int height, int prog_flag, int mc_mm, + int bit10_support, int pack422); + +/*---get di state parameter---*/ +struct di_dev_s *get_dim_de_devp(void); + +const char *dim_get_version_s(void); +int dim_get_dump_state_flag(void); + +int dim_get_blocking(void); + +struct di_buf_s *dim_get_recovery_log_di_buf(void); + +unsigned long dim_get_reg_unreg_timeout_cnt(void); +struct vframe_s **dim_get_vframe_in(unsigned int ch); +int dim_check_recycle_buf(unsigned int channel); + +int dim_seq_file_module_para_di(struct seq_file *seq); +int dim_seq_file_module_para_hw(struct seq_file *seq); + +int dim_seq_file_module_para_film_fw1(struct seq_file *seq); +int dim_seq_file_module_para_mtn(struct seq_file *seq); + +int dim_seq_file_module_para_pps(struct seq_file *seq); + +int dim_seq_file_module_para_(struct seq_file *seq); + +/***********************/ + +unsigned int di_get_dts_nrds_en(void); +int di_get_disp_cnt(void); + +/*---------------------*/ +long dim_pq_load_io(unsigned long arg); +int dim_get_canvas(void); +unsigned int dim_cma_alloc_total(struct di_dev_s *de_devp); +irqreturn_t dim_irq(int irq, void *dev_instance); +irqreturn_t dim_post_irq(int irq, void *dev_instance); + +void dim_rdma_init(void); +void dim_rdma_exit(void); + +void dim_set_di_flag(void); +void dim_get_vpu_clkb(struct device *dev, struct di_dev_s *pdev); + +void dim_log_buffer_state(unsigned char *tag, unsigned int channel); + +unsigned char dim_pre_de_buf_config(unsigned int channel); +void dim_pre_de_process(unsigned int channel); +void dim_pre_de_done_buf_config(unsigned int channel, bool flg_timeout); +void dim_pre_de_done_buf_clear(unsigned int channel); + +void di_reg_setting(unsigned int channel, struct vframe_s *vframe); +void di_reg_variable(unsigned int channel, struct vframe_s *vframe); + +void dim_unreg_process_irq(unsigned int channel); +void di_unreg_variable(unsigned int channel); +void di_unreg_setting(void); + +void dim_uninit_buf(unsigned int disable_mirror, unsigned int channel); +void dim_unreg_process(unsigned int channel); + +int dim_process_post_vframe(unsigned int channel); +unsigned char dim_check_di_buf(struct di_buf_s *di_buf, int reason, + unsigned int channel); +int dim_do_post_wr_fun(void *arg, vframe_t *disp_vf); +int dim_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); +void dim_post_de_done_buf_config(unsigned int channel); +void dim_recycle_post_back(unsigned int channel); +void recycle_post_ready_local(struct di_buf_s *di_buf, + unsigned int channel); + +/*--------------------------*/ +unsigned char dim_vcry_get_flg(void); +void dim_vcry_flg_inc(void); +void dim_vcry_set_flg(unsigned char val); +/*--------------------------*/ +unsigned int dim_vcry_get_log_reason(void); +void dim_vcry_set_log_reason(unsigned int val); +/*--------------------------*/ +unsigned char dim_vcry_get_log_q_idx(void); +void dim_vcry_set_log_q_idx(unsigned int val); +/*--------------------------*/ +struct di_buf_s **dim_vcry_get_log_di_buf(void); +void dim_vcry_set_log_di_buf(struct di_buf_s *di_bufp); +void dim_vcry_set(unsigned int reason, unsigned int idx, + struct di_buf_s *di_bufp); + +const char *dim_get_vfm_type_name(unsigned int nub); + +bool dim_cma_top_alloc(unsigned int ch); +bool dim_cma_top_release(unsigned int ch); + +int dim_get_reg_unreg_cnt(void); +void dim_reg_timeout_inc(void); + +void dim_reg_process(unsigned int channel); +bool is_bypass2(struct vframe_s *vf_in, unsigned int ch); + +/*--------------------------*/ +int di_ori_event_unreg(unsigned int channel); +int di_ori_event_reg(void *data, unsigned int channel); +int di_ori_event_qurey_vdin2nr(unsigned int channel); +int di_ori_event_reset(unsigned int channel); +int di_ori_event_light_unreg(unsigned int channel); +int di_ori_event_light_unreg_revframe(unsigned int channel); +int di_ori_event_ready(unsigned int channel); +int di_ori_event_qurey_state(unsigned int channel); +void di_ori_event_set_3D(int type, void *data, unsigned int channel); + +/*--------------------------*/ +extern int pre_run_flag; +extern unsigned int dbg_first_cnt_pre; +extern spinlock_t plist_lock; + +void dim_dbg_pre_cnt(unsigned int channel, char *item); + +void diext_clk_b_sw(bool on); + +int di_vf_l_states(struct vframe_states *states, unsigned int channel); +struct vframe_s *di_vf_l_peek(unsigned int channel); +void di_vf_l_put(struct vframe_s *vf, unsigned char channel); +struct vframe_s *di_vf_l_get(unsigned int channel); + +unsigned char pre_p_asi_de_buf_config(unsigned int ch); + +/*---------------------*/ + +ssize_t +store_config(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +ssize_t +store_dbg(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +ssize_t +store_dump_mem(struct device *dev, struct device_attribute *attr, + const char *buf, size_t len); +ssize_t +store_log(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count); +ssize_t +show_vframe_status(struct device *dev, + struct device_attribute *attr, + char *buf); + +ssize_t dim_read_log(char *buf); + +/*---------------------*/ + +struct di_buf_s *dim_get_buf(unsigned int channel, + int queue_idx, int *start_pos); + +#define queue_for_each_entry(di_buf, channel, queue_idx, list) \ + for (itmp = 0; \ + ((di_buf = dim_get_buf(channel, queue_idx, &itmp)) != NULL);) + +#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) + +/*this is debug for buf*/ +/*#define DI_DEBUG_POST_BUF_FLOW (1)*/ + +#endif diff --git a/drivers/amlogic/media/di_multi/deinterlace_dbg.c b/drivers/amlogic/media/di_multi/deinterlace_dbg.c new file mode 100644 index 0000000..153f6e0 --- /dev/null +++ b/drivers/amlogic/media/di_multi/deinterlace_dbg.c @@ -0,0 +1,1214 @@ +/* + * drivers/amlogic/media/di_multi/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 "register.h" +#include "deinterlace_dbg.h" +#include "di_pps.h" +#include "nr_downscale.h" +#include +#include "deinterlace.h" + +#include "di_data_l.h" +#include "di_que.h" +#include "di_prc.h" +#include "di_pre.h" +#include "di_post.h" + +#include "di_vframe.h" + +/*2018-07-18 add debugfs*/ +#include +#include +/*2018-07-18 -----------*/ + +void dim_parse_cmd_params(char *buf_orig, char **parm) +{ + char *ps, *token; + char delim1[3] = " "; + char delim2[2] = "\n"; + unsigned int n = 0; + + strcat(delim1, delim2); + ps = buf_orig; + while (1) { + token = strsep(&ps, delim1); + if (!token) + break; + if (*token == '\0') + continue; + parm[n++] = token; + } +} + +static const unsigned int size_reg_addr1[] = { + 0x1702, 0x1703, 0x2d01, + 0x2d01, 0x2d8f, 0x2d08, + 0x2d09, 0x2f00, 0x2f01, + 0x17d0, 0x17d1, 0x17d2, + 0x17d3, 0x17dd, 0x17de, + 0x17df, 0x17e0, 0x17f7, + 0x17f8, 0x17f9, 0x17fa, + 0x17c0, 0x17c1, 0x17a0, + 0x17a1, 0x17c3, 0x17c4, + 0x17cb, 0x17cc, 0x17a3, + 0x17a4, 0x17a5, 0x17a6, + 0x2f92, 0x2f93, 0x2f95, + 0x2f96, 0x2f98, 0x2f99, + 0x2f9b, 0x2f9c, 0x2f65, + 0x2f66, 0x2f67, 0x2f68, + 0x1a53, 0x1a54, 0x1a55, + 0x1a56, 0x17ea, 0x17eb, + 0x17ec, 0x17ed, 0x2012, + 0x2013, 0x2014, 0x2015, + 0xffff +}; + +/*g12 new added*/ +static const unsigned int size_reg_addr2[] = { + 0x37d2, 0x37d3, 0x37d7, + 0x37d8, 0x37dc, 0x37dd, + 0x37e1, 0x37e2, 0x37e6, + 0x37e7, 0x37e9, 0x37ea, + 0x37ed, 0x37ee, 0x37f1, + 0x37f2, 0x37f4, 0x37f5, + 0x37f6, 0x37f8, 0x3751, + 0x3752, 0x376e, 0x376f, + 0x37f9, 0x37fa, 0x37fc, + 0x3740, 0x3757, 0x3762, + 0xffff +}; + +/*2018-08-17 add debugfs*/ +static int seq_file_dump_di_reg_show(struct seq_file *seq, void *v) +{ + unsigned int i = 0, base_addr = 0; + + if (is_meson_txlx_cpu() || is_meson_txhd_cpu()) + base_addr = 0xff900000; + else + base_addr = 0xd0100000; + + seq_puts(seq, "----dump di reg----\n"); + seq_puts(seq, "----dump size reg---\n"); + /*txl crash when dump 0x37d2~0x3762 of size_reg_addr*/ + for (i = 0; size_reg_addr1[i] != 0xffff; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((size_reg_addr1[i]) << 2), + size_reg_addr1[i], dim_RDMA_RD(size_reg_addr1[i])); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + for (i = 0; size_reg_addr2[i] != 0xffff; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((size_reg_addr2[i]) << 2), + size_reg_addr2[i], + dim_RDMA_RD(size_reg_addr2[i])); + } + for (i = 0; i < 255; i++) { + if (i == 0x45) + seq_puts(seq, "----nr reg----"); + if (i == 0x80) + seq_puts(seq, "----3d reg----"); + if (i == 0x9e) + seq_puts(seq, "---nr reg done---"); + if (i == 0x9c) + seq_puts(seq, "---3d reg done---"); + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x1700 + i) << 2), + 0x1700 + i, dim_RDMA_RD(0x1700 + i)); + } + for (i = 0; i < 4; i++) { + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x20ab + i) << 2), + 0x20ab + i, dim_RDMA_RD(0x20ab + i)); + } + seq_puts(seq, "----dump mcdi reg----\n"); + for (i = 0; i < 201; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2f00 + i) << 2), + 0x2f00 + i, dim_RDMA_RD(0x2f00 + i)); + seq_puts(seq, "----dump pulldown reg----\n"); + for (i = 0; i < 26; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2fd0 + i) << 2), + 0x2fd0 + i, dim_RDMA_RD(0x2fd0 + i)); + seq_puts(seq, "----dump bit mode reg----\n"); + for (i = 0; i < 4; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x20a7 + i) << 2), + 0x20a7 + i, dim_RDMA_RD(0x20a7 + i)); + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + (0x2022 << 2), + 0x2022, dim_RDMA_RD(0x2022)); + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + (0x17c1 << 2), + 0x17c1, dim_RDMA_RD(0x17c1)); + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + (0x17c2 << 2), + 0x17c2, dim_RDMA_RD(0x17c2)); + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + (0x1aa7 << 2), + 0x1aa7, dim_RDMA_RD(0x1aa7)); + seq_puts(seq, "----dump dnr reg----\n"); + for (i = 0; i < 29; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2d00 + i) << 2), + 0x2d00 + i, dim_RDMA_RD(0x2d00 + i)); + seq_puts(seq, "----dump if0 reg----\n"); + for (i = 0; i < 26; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x1a60 + i) << 2), + 0x1a50 + i, dim_RDMA_RD(0x1a50 + i)); + seq_puts(seq, "----dump gate reg----\n"); + seq_printf(seq, "[0x%x][0x1718]=0x%x\n", + base_addr + ((0x1718) << 2), + dim_RDMA_RD(0x1718)); + for (i = 0; i < 5; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2006 + i) << 2), + 0x2006 + i, dim_RDMA_RD(0x2006 + i)); + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2dff) << 2), + 0x2dff, dim_RDMA_RD(0x2dff)); + seq_puts(seq, "----dump if2 reg----\n"); + for (i = 0; i < 29; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + ((0x2010 + i) << 2), + 0x2010 + i, dim_RDMA_RD(0x2010 + i)); + if (!is_meson_txl_cpu()) { + seq_puts(seq, "----dump nr4 reg----\n"); + for (i = 0x2da4; i < 0x2df6; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), + i, dim_RDMA_RD(i)); + for (i = 0x3700; i < 0x373f; i++) + seq_printf(seq, "[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), + i, dim_RDMA_RD(i)); + } + seq_puts(seq, "----dump reg done----\n"); + return 0; +} + +static void dump_mif_state(struct DI_MIF_s *mif) +{ + pr_info("luma <%u, %u> <%u %u>.\n", + mif->luma_x_start0, mif->luma_x_end0, + mif->luma_y_start0, mif->luma_y_end0); + pr_info("chroma <%u, %u> <%u %u>.\n", + mif->chroma_x_start0, mif->chroma_x_end0, + mif->chroma_y_start0, mif->chroma_y_end0); + pr_info("canvas id <%u %u %u>.\n", + mif->canvas0_addr0, + mif->canvas0_addr1, + mif->canvas0_addr2); +} + +/*2018-08-17 add debugfs*/ +/*same as dump_mif_state*/ +static void dump_mif_state_seq(struct DI_MIF_s *mif, + struct seq_file *seq) +{ + seq_printf(seq, "luma <%u, %u> <%u %u>.\n", + mif->luma_x_start0, mif->luma_x_end0, + mif->luma_y_start0, mif->luma_y_end0); + seq_printf(seq, "chroma <%u, %u> <%u %u>.\n", + mif->chroma_x_start0, mif->chroma_x_end0, + mif->chroma_y_start0, mif->chroma_y_end0); + seq_printf(seq, "canvas id <%u %u %u>.\n", + mif->canvas0_addr0, + mif->canvas0_addr1, + mif->canvas0_addr2); +} + +static void dump_simple_mif_state(struct DI_SIM_MIF_s *simp_mif) +{ + pr_info("<%u %u> <%u %u>.\n", + simp_mif->start_x, simp_mif->end_x, + simp_mif->start_y, simp_mif->end_y); + pr_info("canvas num <%u>.\n", + simp_mif->canvas_num); +} + +/*2018-08-17 add debugfs*/ +/*same as dump_simple_mif_state*/ +static void dump_simple_mif_state_seq(struct DI_SIM_MIF_s *simp_mif, + struct seq_file *seq) +{ + seq_printf(seq, "<%u %u> <%u %u>.\n", + simp_mif->start_x, simp_mif->end_x, + simp_mif->start_y, simp_mif->end_y); + seq_printf(seq, "canvas num <%u>.\n", + simp_mif->canvas_num); +} + +static void dump_mc_mif_state(struct DI_MC_MIF_s *mc_mif) +{ + pr_info("startx %u,<%u %u>, size <%u %u>.\n", + mc_mif->start_x, mc_mif->start_y, + mc_mif->end_y, mc_mif->size_x, + mc_mif->size_y); +} + +/*2018-08-17 add debugfs*/ +/*same as dump_mc_mif_state*/ +static void dump_mc_mif_state_seq(struct DI_MC_MIF_s *mc_mif, + struct seq_file *seq) +{ + seq_printf(seq, "startx %u,<%u %u>, size <%u %u>.\n", + mc_mif->start_x, mc_mif->start_y, + mc_mif->end_y, mc_mif->size_x, + mc_mif->size_y); +} + +void dim_dump_pre_stru(struct di_pre_stru_s *ppre) +{ + pr_info("di_pre_stru:\n"); + pr_info("di_mem_buf_dup_p = 0x%p\n", + ppre->di_mem_buf_dup_p); + pr_info("di_chan2_buf_dup_p = 0x%p\n", + ppre->di_chan2_buf_dup_p); + pr_info("in_seq = %d\n", + ppre->in_seq); + pr_info("recycle_seq = %d\n", + ppre->recycle_seq); + pr_info("pre_ready_seq = %d\n", + ppre->pre_ready_seq); + pr_info("pre_de_busy = %d\n", + ppre->pre_de_busy); + + pr_info("pre_de_process_flag = %d\n", + ppre->pre_de_process_flag); + pr_info("pre_de_irq_timeout_count=%d\n", + ppre->pre_de_irq_timeout_count); + + pr_info("cur_width = %d\n", + ppre->cur_width); + pr_info("cur_height = %d\n", + ppre->cur_height); + pr_info("cur_inp_type = 0x%x\n", + ppre->cur_inp_type); + pr_info("cur_source_type = %d\n", + ppre->cur_source_type); + pr_info("cur_prog_flag = %d\n", + ppre->cur_prog_flag); + pr_info("source_change_flag = %d\n", + ppre->source_change_flag); + pr_info("bypass_flag = %s\n", + ppre->bypass_flag ? "true" : "false"); + pr_info("prog_proc_type = %d\n", + ppre->prog_proc_type); + pr_info("madi_enable = %u\n", + ppre->madi_enable); + pr_info("mcdi_enable = %u\n", + ppre->mcdi_enable); +#ifdef DET3D + pr_info("vframe_interleave_flag = %d\n", + ppre->vframe_interleave_flag); +#endif + pr_info("left_right = %d\n", + ppre->left_right); + pr_info("force_interlace = %s\n", + ppre->force_interlace ? "true" : "false"); + pr_info("vdin2nr = %d\n", + ppre->vdin2nr); + pr_info("bypass_pre = %s\n", + ppre->bypass_pre ? "true" : "false"); + pr_info("invert_flag = %s\n", + ppre->invert_flag ? "true" : "false"); +} + +/*2018-08-17 add debugfs*/ +/*same as dim_dump_pre_stru*/ +static int dump_di_pre_stru_seq(struct seq_file *seq, void *v, + unsigned int channel) + +{ + struct di_pre_stru_s *di_pre_stru_p = get_pre_stru(channel); + + seq_printf(seq, "di_pre_stru[%d]:\n", channel); + seq_printf(seq, "%-25s = 0x%p\n", "di_mem_buf_dup_p", + di_pre_stru_p->di_mem_buf_dup_p); + seq_printf(seq, "%-25s = 0x%p\n", "di_chan2_buf_dup_p", + di_pre_stru_p->di_chan2_buf_dup_p); + seq_printf(seq, "%-25s = %d\n", "in_seq", + di_pre_stru_p->in_seq); + seq_printf(seq, "%-25s = %d\n", "recycle_seq", + di_pre_stru_p->recycle_seq); + seq_printf(seq, "%-25s = %d\n", "pre_ready_seq", + di_pre_stru_p->pre_ready_seq); + seq_printf(seq, "%-25s = %d\n", "pre_de_busy", + di_pre_stru_p->pre_de_busy); + seq_printf(seq, "%-25s = %d\n", "pre_de_process_flag", + di_pre_stru_p->pre_de_process_flag); + seq_printf(seq, "%-25s =%d\n", "pre_de_irq_timeout_count", + di_pre_stru_p->pre_de_irq_timeout_count); + seq_printf(seq, "%-25s = %d\n", "cur_width", + di_pre_stru_p->cur_width); + seq_printf(seq, "%-25s = %d\n", "cur_height", + di_pre_stru_p->cur_height); + seq_printf(seq, "%-25s = 0x%x\n", "cur_inp_type", + di_pre_stru_p->cur_inp_type); + seq_printf(seq, "%-25s = %d\n", "cur_source_type", + di_pre_stru_p->cur_source_type); + seq_printf(seq, "%-25s = %d\n", "cur_prog_flag", + di_pre_stru_p->cur_prog_flag); + seq_printf(seq, "%-25s = %d\n", "source_change_flag", + di_pre_stru_p->source_change_flag); + seq_printf(seq, "%-25s = %s\n", "bypass_flag", + di_pre_stru_p->bypass_flag ? "true" : "false"); + seq_printf(seq, "%-25s = %d\n", "prog_proc_type", + di_pre_stru_p->prog_proc_type); + seq_printf(seq, "%-25s = %d\n", "madi_enable", + di_pre_stru_p->madi_enable); + seq_printf(seq, "%-25s = %d\n", "mcdi_enable", + di_pre_stru_p->mcdi_enable); +#ifdef DET3D + seq_printf(seq, "%-25s = %d\n", "vframe_interleave_flag", + di_pre_stru_p->vframe_interleave_flag); +#endif + seq_printf(seq, "%-25s = %d\n", "left_right", + di_pre_stru_p->left_right); + seq_printf(seq, "%-25s = %s\n", "force_interlace", + di_pre_stru_p->force_interlace ? "true" : "false"); + seq_printf(seq, "%-25s = %d\n", "vdin2nr", + di_pre_stru_p->vdin2nr); + seq_printf(seq, "%-25s = %s\n", "bypass_pre", + di_pre_stru_p->bypass_pre ? "true" : "false"); + seq_printf(seq, "%-25s = %s\n", "invert_flag", + di_pre_stru_p->invert_flag ? "true" : "false"); + + return 0; +} + +void dim_dump_post_stru(struct di_post_stru_s *di_post_stru_p) +{ + pr_info("\ndi_post_stru:\n"); + pr_info("run_early_proc_fun_flag = %d\n", + di_post_stru_p->run_early_proc_fun_flag); + pr_info("cur_disp_index = %d\n", + di_post_stru_p->cur_disp_index); + pr_info("post_de_busy = %d\n", + di_post_stru_p->post_de_busy); + pr_info("de_post_process_done = %d\n", + di_post_stru_p->de_post_process_done); + pr_info("cur_post_buf = 0x%p\n", + di_post_stru_p->cur_post_buf); + pr_info("post_peek_underflow = %u\n", + di_post_stru_p->post_peek_underflow); +} + +/*2018-08-17 add debugfs*/ +/*same as dim_dump_post_stru*/ +static int dump_di_post_stru_seq(struct seq_file *seq, void *v, + unsigned int channel) +{ + struct di_post_stru_s *di_post_stru_p = get_post_stru(channel); + + seq_printf(seq, "di_post_stru[%d]:\n", channel); + seq_printf(seq, "run_early_proc_fun_flag = %d\n", + di_post_stru_p->run_early_proc_fun_flag); + seq_printf(seq, "cur_disp_index = %d\n", + di_post_stru_p->cur_disp_index); + seq_printf(seq, "post_de_busy = %d\n", + di_post_stru_p->post_de_busy); + seq_printf(seq, "de_post_process_done = %d\n", + di_post_stru_p->de_post_process_done); + seq_printf(seq, "cur_post_buf = 0x%p\n", + di_post_stru_p->cur_post_buf); + seq_printf(seq, "post_peek_underflow = %u\n", + di_post_stru_p->post_peek_underflow); + + return 0; +} + +void dim_dump_mif_size_state(struct di_pre_stru_s *pre_stru_p, + struct di_post_stru_s *post_stru_p) +{ + pr_info("======pre mif status======\n"); + pr_info("DI_PRE_CTRL=0x%x\n", Rd(DI_PRE_CTRL)); + pr_info("DI_PRE_SIZE H=%d, V=%d\n", + (Rd(DI_PRE_SIZE) >> 16) & 0xffff, + Rd(DI_PRE_SIZE) & 0xffff); + pr_info("DNR_HVSIZE=0x%x\n", Rd(DNR_HVSIZE)); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + pr_info("CONTWR_CAN_SIZE=0x%x\n", Rd(0x37ec)); + pr_info("MTNWR_CAN_SIZE=0x%x\n", Rd(0x37f0)); + } + pr_info("DNR_STAT_X_START_END=0x%x\n", Rd(0x2d08)); + pr_info("DNR_STAT_Y_START_END=0x%x\n", Rd(0x2d09)); + pr_info("MCDI_HV_SIZEIN=0x%x\n", Rd(0x2f00)); + pr_info("MCDI_HV_BLKSIZEIN=0x%x\n", Rd(0x2f01)); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + pr_info("MCVECWR_CAN_SIZE=0x%x\n", Rd(0x37f4)); + pr_info("MCINFWR_CAN_SIZE=0x%x\n", Rd(0x37f8)); + pr_info("NRDSWR_CAN_SIZE=0x%x\n", Rd(0x37fc)); + pr_info("NR_DS_BUF_SIZE=0x%x\n", Rd(0x3740)); + } + + pr_info("=====inp mif:\n"); +#if 0 + Wr(DI_DBG_CTRL, 0x1b); + Wr(DI_DBG_CTRL1, 0x640064); + Wr_reg_bits(DI_PRE_GL_CTRL, 0, 31, 1); + Wr_reg_bits(DI_PRE_CTRL, 0, 11, 1); + Wr_reg_bits(DI_PRE_CTRL, 1, 31, 1); + Wr_reg_bits(DI_PRE_GL_CTRL, 1, 31, 1); + pr_info("DI_DBG_SRDY_INF=0x%x\n", Rd(DI_DBG_SRDY_INF)); + pr_info("DI_DBG_RRDY_INF=0x%x\n", Rd(DI_DBG_RRDY_INF)); +#endif + pr_info("DI_INP_GEN_REG=0x%x\n", Rd(DI_INP_GEN_REG)); + dump_mif_state(&pre_stru_p->di_inp_mif); + pr_info("=====mem mif:\n"); + pr_info("DI_MEM_GEN_REG=0x%x\n", Rd(DI_MEM_GEN_REG)); + dump_mif_state(&pre_stru_p->di_mem_mif); + pr_info("=====chan2 mif:\n"); + pr_info("DI_CHAN2_GEN_REG=0x%x\n", Rd(DI_CHAN2_GEN_REG)); + dump_mif_state(&pre_stru_p->di_chan2_mif); + pr_info("=====nrwr mif:\n"); + pr_info("DI_NRWR_CTRL=0x%x\n", Rd(DI_NRWR_CTRL)); + dump_simple_mif_state(&pre_stru_p->di_nrwr_mif); + pr_info("=====mtnwr mif:\n"); + dump_simple_mif_state(&pre_stru_p->di_mtnwr_mif); + pr_info("=====contp2rd mif:\n"); + dump_simple_mif_state(&pre_stru_p->di_contp2rd_mif); + pr_info("=====contprd mif:\n"); + dump_simple_mif_state(&pre_stru_p->di_contprd_mif); + pr_info("=====contwr mif:\n"); + dump_simple_mif_state(&pre_stru_p->di_contwr_mif); + pr_info("=====mcinford mif:\n"); + dump_mc_mif_state(&pre_stru_p->di_mcinford_mif); + pr_info("=====mcinfowr mif:\n"); + dump_mc_mif_state(&pre_stru_p->di_mcinfowr_mif); + pr_info("=====mcvecwr mif:\n"); + dump_mc_mif_state(&pre_stru_p->di_mcvecwr_mif); + pr_info("======post mif status======\n"); + pr_info("DI_POST_SIZE=0x%x\n", Rd(DI_POST_SIZE)); + pr_info("DECOMB_FRM_SIZE=0x%x\n", Rd(0x2d8f)); + pr_info("=====if0 mif:\n"); + pr_info("DI_IF0_GEN_REG=0x%x\n", Rd(0x2030)); + dump_mif_state(&post_stru_p->di_buf0_mif); + pr_info("=====if1 mif:\n"); + pr_info("DI_IF1_GEN_REG=0x%x\n", Rd(0x17e8)); + dump_mif_state(&post_stru_p->di_buf1_mif); + pr_info("=====if2 mif:\n"); + pr_info("DI_IF2_GEN_REG=0x%x\n", Rd(0x2010)); + dump_mif_state(&post_stru_p->di_buf2_mif); + pr_info("=====diwr mif:\n"); + dump_simple_mif_state(&post_stru_p->di_diwr_mif); + pr_info("=====mtnprd mif:\n"); + dump_simple_mif_state(&post_stru_p->di_mtnprd_mif); + pr_info("=====mcvecrd mif:\n"); + dump_mc_mif_state(&post_stru_p->di_mcvecrd_mif); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + pr_info("======pps size status======\n"); + pr_info("DI_SC_LINE_IN_LENGTH=0x%x\n", Rd(0x3751)); + pr_info("DI_SC_PIC_IN_HEIGHT=0x%x\n", Rd(0x3752)); + pr_info("DI_HDR_IN_HSIZE=0x%x\n", Rd(0x376e)); + pr_info("DI_HDR_IN_VSIZE=0x%x\n", Rd(0x376f)); + } +} + +/*2018-08-17 add debugfs*/ +/*same as dump_mif_size_state*/ +int dim_dump_mif_size_state_show(struct seq_file *seq, + void *v, unsigned int channel) +{ + struct di_pre_stru_s *di_pre_stru_p; + struct di_post_stru_s *di_post_stru_p; + + di_pre_stru_p = get_pre_stru(channel); + di_post_stru_p = get_post_stru(channel); + + seq_puts(seq, "======pre mif status======\n"); + seq_printf(seq, "DI_PRE_CTRL=0x%x\n", Rd(DI_PRE_CTRL)); + seq_printf(seq, "DI_PRE_SIZE=0x%x\n", Rd(DI_PRE_SIZE)); + seq_printf(seq, "DNR_HVSIZE=0x%x\n", Rd(DNR_HVSIZE)); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + seq_printf(seq, "CONTWR_CAN_SIZE=0x%x\n", Rd(0x37ec)); + seq_printf(seq, "MTNWR_CAN_SIZE=0x%x\n", Rd(0x37f0)); + } + seq_printf(seq, "DNR_STAT_X_START_END=0x%x\n", Rd(0x2d08)); + seq_printf(seq, "DNR_STAT_Y_START_END=0x%x\n", Rd(0x2d09)); + seq_printf(seq, "MCDI_HV_SIZEIN=0x%x\n", Rd(0x2f00)); + seq_printf(seq, "MCDI_HV_BLKSIZEIN=0x%x\n", Rd(0x2f01)); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + seq_printf(seq, "MCVECWR_CAN_SIZE=0x%x\n", Rd(0x37f4)); + seq_printf(seq, "MCINFWR_CAN_SIZE=0x%x\n", Rd(0x37f8)); + seq_printf(seq, "NRDSWR_CAN_SIZE=0x%x\n", Rd(0x37fc)); + seq_printf(seq, "NR_DS_BUF_SIZE=0x%x\n", Rd(0x3740)); + } + + seq_puts(seq, "=====inp mif:\n"); + + seq_printf(seq, "DI_INP_GEN_REG=0x%x\n", Rd(DI_INP_GEN_REG)); + dump_mif_state_seq(&di_pre_stru_p->di_inp_mif, seq);/*dump_mif_state*/ + seq_puts(seq, "=====mem mif:\n"); + seq_printf(seq, "DI_MEM_GEN_REG=0x%x\n", Rd(DI_MEM_GEN_REG)); + dump_mif_state_seq(&di_pre_stru_p->di_mem_mif, seq); + seq_puts(seq, "=====chan2 mif:\n"); + seq_printf(seq, "DI_CHAN2_GEN_REG=0x%x\n", Rd(DI_CHAN2_GEN_REG)); + dump_mif_state_seq(&di_pre_stru_p->di_chan2_mif, seq); + seq_puts(seq, "=====nrwr mif:\n"); + seq_printf(seq, "DI_NRWR_CTRL=0x%x\n", Rd(DI_NRWR_CTRL)); + /*dump_simple_mif_state*/ + dump_simple_mif_state_seq(&di_pre_stru_p->di_nrwr_mif, seq); + seq_puts(seq, "=====mtnwr mif:\n"); + dump_simple_mif_state_seq(&di_pre_stru_p->di_mtnwr_mif, seq); + seq_puts(seq, "=====contp2rd mif:\n"); + dump_simple_mif_state_seq(&di_pre_stru_p->di_contp2rd_mif, seq); + seq_puts(seq, "=====contprd mif:\n"); + dump_simple_mif_state_seq(&di_pre_stru_p->di_contprd_mif, seq); + seq_puts(seq, "=====contwr mif:\n"); + dump_simple_mif_state_seq(&di_pre_stru_p->di_contwr_mif, seq); + seq_puts(seq, "=====mcinford mif:\n"); + /*dump_mc_mif_state*/ + dump_mc_mif_state_seq(&di_pre_stru_p->di_mcinford_mif, seq); + seq_puts(seq, "=====mcinfowr mif:\n"); + dump_mc_mif_state_seq(&di_pre_stru_p->di_mcinfowr_mif, seq); + seq_puts(seq, "=====mcvecwr mif:\n"); + dump_mc_mif_state_seq(&di_pre_stru_p->di_mcvecwr_mif, seq); + seq_puts(seq, "======post mif status======\n"); + seq_printf(seq, "DI_POST_SIZE=0x%x\n", Rd(DI_POST_SIZE)); + seq_printf(seq, "DECOMB_FRM_SIZE=0x%x\n", Rd(0x2d8f)); + seq_puts(seq, "=====if0 mif:\n"); + seq_printf(seq, "DI_IF0_GEN_REG=0x%x\n", Rd(0x2030)); + dump_mif_state_seq(&di_post_stru_p->di_buf0_mif, seq); + seq_puts(seq, "=====if1 mif:\n"); + seq_printf(seq, "DI_IF1_GEN_REG=0x%x\n", Rd(0x17e8)); + dump_mif_state_seq(&di_post_stru_p->di_buf1_mif, seq); + seq_puts(seq, "=====if2 mif:\n"); + seq_printf(seq, "DI_IF2_GEN_REG=0x%x\n", Rd(0x2010)); + dump_mif_state_seq(&di_post_stru_p->di_buf2_mif, seq); + seq_puts(seq, "=====diwr mif:\n"); + dump_simple_mif_state_seq(&di_post_stru_p->di_diwr_mif, seq); + seq_puts(seq, "=====mtnprd mif:\n"); + dump_simple_mif_state_seq(&di_post_stru_p->di_mtnprd_mif, seq); + seq_puts(seq, "=====mcvecrd mif:\n"); + dump_mc_mif_state_seq(&di_post_stru_p->di_mcvecrd_mif, seq); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + seq_puts(seq, "======pps size status======\n"); + seq_printf(seq, "DI_SC_LINE_IN_LENGTH=0x%x\n", Rd(0x3751)); + seq_printf(seq, "DI_SC_PIC_IN_HEIGHT=0x%x\n", Rd(0x3752)); + seq_printf(seq, "DI_HDR_IN_HSIZE=0x%x\n", Rd(0x376e)); + seq_printf(seq, "DI_HDR_IN_VSIZE=0x%x\n", Rd(0x376f)); + } + return 0; +} + +void dim_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->pd_config.global_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 dim_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 dim_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 dim_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); + } + } +} + +/*2018-08-17 add debugfs*/ +/*same as print_di_buf*/ +static void print_di_buf_seq(struct di_buf_s *di_buf, int format, + struct seq_file *seq) +{ + if (!di_buf) + return; + if (format == 1) { + seq_printf(seq, "\t+index %d, 0x%p, type %d\n", + di_buf->index, + di_buf, + di_buf->type); + seq_printf(seq, "vframetype 0x%x, trans_fmt %u,bitdepath %d\n", + di_buf->vframe->type, + di_buf->vframe->trans_fmt, + di_buf->vframe->bitdepth); + if (di_buf->di_wr_linked_buf) { + seq_printf(seq, "\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) { + seq_printf(seq, "index %d, 0x%p(vframe 0x%p), type %d\n", + di_buf->index, di_buf, + di_buf->vframe, di_buf->type); + seq_printf(seq, "vfmtype 0x%x, trans_fmt %u\n", + di_buf->vframe->type, + di_buf->vframe->trans_fmt); + seq_printf(seq, ",duration %d pts %d,bitdepth %d\n", + di_buf->vframe->duration, + di_buf->vframe->pts, + di_buf->vframe->bitdepth); + if (di_buf->di_wr_linked_buf) { + seq_printf(seq, "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); + } + } +} + +void dim_dump_pre_mif_state(void) +{ + unsigned int i = 0; + + Wr_reg_bits(DI_INP_GEN_REG3, 3, 10, 2); + Wr_reg_bits(DI_MEM_GEN_REG3, 3, 10, 2); + Wr_reg_bits(DI_CHAN2_GEN_REG3, 3, 10, 2); + pr_info("DI_INP_GEN_REG2=0x%x.\n", Rd(DI_INP_GEN_REG2)); + pr_info("DI_INP_GEN_REG3=0x%x.\n", Rd(DI_INP_GEN_REG3)); + for (i = 0; i < 10; i++) + pr_info("0x%x=0x%x.\n", 0x17ce + i, Rd(0x17ce + i)); + pr_info("DI_MEM_GEN_REG2=0x%x.\n", Rd(DI_MEM_GEN_REG2)); + pr_info("DI_MEM_GEN_REG3=0x%x.\n", Rd(DI_MEM_GEN_REG3)); + pr_info("DI_MEM_LUMA_FIFO_SIZE=0x%x.\n", Rd(DI_MEM_LUMA_FIFO_SIZE)); + for (i = 0; i < 10; i++) + pr_info("0x%x=0x%x.\n", 0x17db + i, Rd(0x17db + i)); + pr_info("DI_CHAN2_GEN_REG2=0x%x.\n", Rd(DI_CHAN2_GEN_REG2)); + pr_info("DI_CHAN2_GEN_REG3=0x%x.\n", Rd(DI_CHAN2_GEN_REG3)); + pr_info("DI_CHAN2_LUMA_FIFO_SIZE=0x%x.\n", Rd(DI_CHAN2_LUMA_FIFO_SIZE)); + for (i = 0; i < 10; i++) + pr_info("0x%x=0x%x.\n", 0x17f5 + i, Rd(0x17f5 + i)); +} + +void dim_dump_post_mif_reg(void) +{ + pr_info("VIU_MISC_CTRL0=0x%x\n", Rd(VIU_MISC_CTRL0)); + + pr_info("VD1_IF0_GEN_REG=0x%x\n", Rd(VD1_IF0_GEN_REG)); + pr_info("VD1_IF0_GEN_REG2=0x%x\n", Rd(VD1_IF0_GEN_REG2)); + pr_info("VD1_IF0_GEN_REG3=0x%x\n", Rd(VD1_IF0_GEN_REG3)); + pr_info("VD1_IF0_LUMA_X0=0x%x\n", Rd(VD1_IF0_LUMA_X0)); + pr_info("VD1_IF0_LUMA_Y0=0x%x\n", Rd(VD1_IF0_LUMA_Y0)); + pr_info("VD1_IF0_CHROMA_X0=0x%x\n", Rd(VD1_IF0_CHROMA_X0)); + pr_info("VD1_IF0_CHROMA_Y0=0x%x\n", Rd(VD1_IF0_CHROMA_Y0)); + pr_info("VD1_IF0_LUMA_X1=0x%x\n", Rd(VD1_IF0_LUMA_X1)); + pr_info("VD1_IF0_LUMA_Y1=0x%x\n", Rd(VD1_IF0_LUMA_Y1)); + pr_info("VD1_IF0_CHROMA_X1=0x%x\n", Rd(VD1_IF0_CHROMA_X1)); + pr_info("VD1_IF0_CHROMA_Y1=0x%x\n", Rd(VD1_IF0_CHROMA_Y1)); + pr_info("VD1_IF0_REPEAT_LOOP=0x%x\n", Rd(VD1_IF0_RPT_LOOP)); + pr_info("VD1_IF0_LUMA0_RPT_PAT=0x%x\n", Rd(VD1_IF0_LUMA0_RPT_PAT)); + pr_info("VD1_IF0_CHROMA0_RPT_PAT=0x%x\n", Rd(VD1_IF0_CHROMA0_RPT_PAT)); + pr_info("VD1_IF0_LUMA_PSEL=0x%x\n", Rd(VD1_IF0_LUMA_PSEL)); + pr_info("VD1_IF0_CHROMA_PSEL=0x%x\n", Rd(VD1_IF0_CHROMA_PSEL)); + pr_info("VIU_VD1_FMT_CTRL=0x%x\n", Rd(VIU_VD1_FMT_CTRL)); + pr_info("VIU_VD1_FMT_W=0x%x\n", Rd(VIU_VD1_FMT_W)); + + pr_info("DI_IF1_GEN_REG=0x%x\n", Rd(DI_IF1_GEN_REG)); + pr_info("DI_IF1_GEN_REG2=0x%x\n", Rd(DI_IF1_GEN_REG2)); + pr_info("DI_IF1_GEN_REG3=0x%x\n", Rd(DI_IF1_GEN_REG3)); + pr_info("DI_IF1_CANVAS0=0x%x\n", Rd(DI_IF1_CANVAS0)); + pr_info("DI_IF1_LUMA_X0=0x%x\n", Rd(DI_IF1_LUMA_X0)); + pr_info("DI_IF1_LUMA_Y0=0x%x\n", Rd(DI_IF1_LUMA_Y0)); + pr_info("DI_IF1_CHROMA_X0=0x%x\n", Rd(DI_IF1_CHROMA_X0)); + pr_info("DI_IF1_CHROMA_Y0=0x%x\n", Rd(DI_IF1_CHROMA_Y0)); + pr_info("DI_IF1_LUMA0_RPT_PAT=0x%x\n", Rd(DI_IF1_LUMA0_RPT_PAT)); + pr_info("DI_IF1_CHROMA0_RPT_PAT=0x%x\n", Rd(DI_IF1_LUMA0_RPT_PAT)); + pr_info("DI_IF1_FMT_CTRL=0x%x\n", Rd(DI_IF1_FMT_CTRL)); + pr_info("DI_IF1_FMT_W=0x%x\n", Rd(DI_IF1_FMT_W)); + + pr_info("DI_IF2_GEN_REG=0x%x\n", Rd(DI_IF2_GEN_REG)); + pr_info("DI_IF2_GEN_REG2=0x%x\n", Rd(DI_IF2_GEN_REG2)); + pr_info("DI_IF2_GEN_REG3=0x%x\n", Rd(DI_IF2_GEN_REG3)); + pr_info("DI_IF2_CANVAS0=0x%x\n", Rd(DI_IF2_CANVAS0)); + pr_info("DI_IF2_LUMA_X0=0x%x\n", Rd(DI_IF2_LUMA_X0)); + pr_info("DI_IF2_LUMA_Y0=0x%x\n", Rd(DI_IF2_LUMA_Y0)); + pr_info("DI_IF2_CHROMA_X0=0x%x\n", Rd(DI_IF2_CHROMA_X0)); + pr_info("DI_IF2_CHROMA_Y0=0x%x\n", Rd(DI_IF2_CHROMA_Y0)); + pr_info("DI_IF2_LUMA0_RPT_PAT=0x%x\n", Rd(DI_IF2_LUMA0_RPT_PAT)); + pr_info("DI_IF2_CHROMA0_RPT_PAT=0x%x\n", Rd(DI_IF2_LUMA0_RPT_PAT)); + pr_info("DI_IF2_FMT_CTRL=0x%x\n", Rd(DI_IF2_FMT_CTRL)); + pr_info("DI_IF2_FMT_W=0x%x\n", Rd(DI_IF2_FMT_W)); + + pr_info("DI_DIWR_Y=0x%x\n", Rd(DI_DIWR_Y)); + pr_info("DI_DIWR_CTRL=0x%x", Rd(DI_DIWR_CTRL)); + pr_info("DI_DIWR_X=0x%x.\n", Rd(DI_DIWR_X)); +} + +void dim_dump_buf_addr(struct di_buf_s *di_buf, unsigned int num) +{ + unsigned int i = 0; + struct di_buf_s *di_buf_p = NULL; + + for (i = 0; i < num; i++) { + di_buf_p = (di_buf + i); + pr_info("di_buf[%d] nr_addr 0x%lx,", + di_buf_p->index, di_buf_p->nr_adr); + pr_info("mtn_addr 0x%lx, cnt_adr 0x%lx,", + di_buf_p->mtn_adr, di_buf_p->cnt_adr); + pr_info("mv_adr 0x%lx, mcinfo_adr 0x%lx.\n", + di_buf_p->mcvec_adr, di_buf_p->mcinfo_adr); + } +} + +static int seq_file_module_para_show(struct seq_file *seq, void *v) +{ + dim_seq_file_module_para_di(seq); + dim_seq_file_module_para_hw(seq); + dim_seq_file_module_para_pps(seq); + get_ops_mtn()->module_para(seq); + get_ops_nr()->module_para(seq); + get_ops_pd()->module_para(seq); + + return 0; +} + +/*2018-08-17 add debugfs*/ +/*same as dump_state*/ +int dim_state_show(struct seq_file *seq, void *v, unsigned int channel) +{ + int itmp, i; + struct di_buf_s *p = NULL, *keep_buf;/* ptmp; */ + struct di_pre_stru_s *di_pre_stru_p; + struct di_post_stru_s *di_post_stru_p; + struct di_dev_s *de_devp = get_dim_de_devp(); + const char *version_s = dim_get_version_s(); + int dump_state_flag = dim_get_dump_state_flag(); + unsigned char recovery_flag = dim_vcry_get_flg(); + unsigned int recovery_log_reason = dim_vcry_get_log_reason(); + int di_blocking = dim_get_blocking(); + unsigned int recovery_log_queue_idx = dim_vcry_get_log_q_idx(); + struct di_buf_s *recovery_log_di_buf = dim_get_recovery_log_di_buf(); + unsigned long reg_unreg_timeout_cnt = dim_get_reg_unreg_timeout_cnt(); + struct vframe_s **vframe_in = dim_get_vframe_in(channel); + unsigned int tmpa[MAX_FIFO_SIZE]; /*new que*/ + unsigned int psize; /*new que*/ + struct di_hpre_s *pre = get_hw_pre(); + struct di_hpst_s *post = get_hw_pst(); + struct di_buf_s *keep_buf_post = NULL; + char *splt = "---------------------------"; + struct di_mm_s *mm = dim_mm_get(); /*mm-0705*/ + + di_pre_stru_p = get_pre_stru(channel); + di_post_stru_p = get_post_stru(channel); + + dump_state_flag = 1; + seq_printf(seq, "%s:ch[%d]\n", __func__, channel); + seq_printf(seq, "version %s, init_flag %d, is_bypass %d\n", + version_s, + get_init_flag(channel), + dim_is_bypass(NULL, channel)); + seq_printf(seq, "recovery_flag = %d, reason=%d, di_blocking=%d", + recovery_flag, recovery_log_reason, di_blocking); + seq_printf(seq, "recovery_log_q_idx=%d, recovery_log_di_buf=0x%p\n", + recovery_log_queue_idx, recovery_log_di_buf); + seq_printf(seq, "buffer_size=%d, mem_flag=%s, cma_flag=%d\n", + de_devp->buffer_size, + di_cma_dbg_get_st_name(channel), + de_devp->flag_cma); + keep_buf = di_post_stru_p->keep_buf; + seq_printf(seq, "used_post_buf_index %d(0x%p),", + IS_ERR_OR_NULL(keep_buf) ? + -1 : keep_buf->index, keep_buf); + if (!IS_ERR_OR_NULL(keep_buf)) { + seq_puts(seq, "used_local_buf_index:\n"); + for (i = 0; i < USED_LOCAL_BUF_MAX; i++) { + p = keep_buf->di_buf_dup_p[i]; + seq_printf(seq, "%d(0x%p) ", + IS_ERR_OR_NULL(p) ? -1 : p->index, p); + } + } + /********************************/ + /* check keep buf post */ + /********************************/ + keep_buf_post = di_post_stru_p->keep_buf_post; + + if (IS_ERR_OR_NULL(keep_buf_post)) + seq_printf(seq, "%s:NULL\n", "keep_buf_post"); + else + seq_printf(seq, "%s:type=%d:index=%d\n", + "keep_buf_post", + keep_buf_post->type, keep_buf_post->index); + /********************************/ + /* in_free_list */ + /********************************/ + di_que_list(channel, QUE_IN_FREE, &tmpa[0], &psize); /*new que*/ + seq_printf(seq, "\nin_free_list max(%d) curr(%d):\n", + MAX_IN_BUF_NUM, psize); + for (itmp = 0; itmp < psize; itmp++) { /*new que*/ + p = pw_qindex_2_buf(channel, tmpa[itmp]); /*new que*/ + + seq_printf(seq, "index %2d, 0x%p, type %d\n", + p->index, p, p->type); + } + seq_printf(seq, "%s\n", splt); + /********************************/ + /* local_free_list */ + /********************************/ + seq_printf(seq, "local_free_list (max %d):\n", mm->cfg.num_local); + queue_for_each_entry(p, channel, QUEUE_LOCAL_FREE, list) { + seq_printf(seq, "index %2d, 0x%p, type %d\n", + p->index, p, p->type); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* post_doing_list */ + /********************************/ + seq_puts(seq, "post_doing_list:\n"); + queue_for_each_entry(p, channel, QUEUE_POST_DOING, list) { + print_di_buf_seq(p, 2, seq); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* pre_ready_list */ + /********************************/ + seq_puts(seq, "pre_ready_list:\n"); + di_que_list(channel, QUE_PRE_READY, &tmpa[0], &psize); /*new que*/ + for (itmp = 0; itmp < psize; itmp++) { /*new que*/ + p = pw_qindex_2_buf(channel, tmpa[itmp]); /*new que*/ + + print_di_buf_seq(p, 2, seq); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* post_free_list */ + /********************************/ + di_que_list(channel, QUE_POST_FREE, &tmpa[0], &psize); /*new que*/ + seq_printf(seq, "post_free_list (max %d) (crr %d):\n", + mm->cfg.num_post, psize); + for (itmp = 0; itmp < psize; itmp++) { /*new que*/ + p = pw_qindex_2_buf(channel, tmpa[itmp]); /*new que*/ + + seq_printf(seq, "index %2d, 0x%p, type %d, vframetype 0x%x\n", + p->index, p, p->type, p->vframe->type); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* post_ready_list */ + /********************************/ + di_que_list(channel, QUE_POST_READY, &tmpa[0], &psize); /*new que*/ + seq_printf(seq, "post_ready_list: curr(%d)\n", psize); + + for (itmp = 0; itmp < psize; itmp++) { /*new que*/ + p = pw_qindex_2_buf(channel, tmpa[itmp]); /*new que*/ + + print_di_buf_seq(p, 2, seq); + print_di_buf_seq(p->di_buf[0], 1, seq); + print_di_buf_seq(p->di_buf[1], 1, seq); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* display_list */ + /********************************/ + seq_puts(seq, "display_list:\n"); + queue_for_each_entry(p, channel, QUEUE_DISPLAY, list) { + print_di_buf_seq(p, 2, seq); + print_di_buf_seq(p->di_buf[0], 1, seq); + print_di_buf_seq(p->di_buf[1], 1, seq); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* recycle_list */ + /********************************/ + seq_puts(seq, "recycle_list:\n"); + queue_for_each_entry(p, channel, QUEUE_RECYCLE, list) { + seq_printf(seq, + "index %d, 0x%p, type %d, vfm 0x%x pre %d postt %d\n", + p->index, p, p->type, + p->vframe->type, + p->pre_ref_count, + p->post_ref_count); + if (p->di_wr_linked_buf) { + seq_printf(seq, + "ld index %2d, 0x%p, type %d pret %d pst %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); + } + } + seq_printf(seq, "%s\n", splt); + /********************************/ + /* post back */ + /********************************/ + di_que_list(channel, QUE_POST_BACK, &tmpa[0], &psize); /*new que*/ + seq_printf(seq, "post_back: curr(%d)\n", psize); + + for (itmp = 0; itmp < psize; itmp++) { /*new que*/ + seq_printf(seq, "%d\n", tmpa[itmp]); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + + if (di_pre_stru_p->di_inp_buf) { + seq_printf(seq, "di_inp_buf:index %d, 0x%p, type %d\n", + di_pre_stru_p->di_inp_buf->index, + &di_pre_stru_p->di_inp_buf, + di_pre_stru_p->di_inp_buf->type); + } else { + seq_puts(seq, "di_inp_buf: NULL\n"); + } + if (di_pre_stru_p->di_wr_buf) { + seq_printf(seq, "di_wr_buf:index %d, 0x%p, type %d\n", + di_pre_stru_p->di_wr_buf->index, + &di_pre_stru_p->di_wr_buf, + di_pre_stru_p->di_wr_buf->type); + } else { + seq_puts(seq, "di_wr_buf: NULL\n"); + } + dump_di_pre_stru_seq(seq, v, channel); + dump_di_post_stru_seq(seq, v, channel); + seq_puts(seq, "vframe_in[]:"); + + for (i = 0; i < MAX_IN_BUF_NUM; i++) { + seq_printf(seq, "0x%p\n", *vframe_in); + vframe_in++; + } + + seq_puts(seq, "\n"); + seq_printf(seq, "vf_peek()=>0x%p, video_peek_cnt = %d\n", + pw_vf_peek(channel), + di_sum_get(channel, eDI_SUM_O_PEEK_CNT)); + seq_printf(seq, "reg_unreg_timerout = %lu\n", + reg_unreg_timeout_cnt); + seq_printf(seq, "%-15s=%s\n", "top_state", + dip_chst_get_name_curr(channel)); + seq_printf(seq, "%-15s=%d\n", "trig_unreg", + get_flag_trig_unreg(channel)); + seq_printf(seq, "%-15s=%d\n", "bypass_compelet", + is_bypss2_complete(channel)); + seq_printf(seq, "%-15s=%d\n", "reg_flag", + get_reg_flag(channel)); + seq_printf(seq, "%-15s=%s\n", "pre_state", + dpre_state4_name_get(pre->pre_st)); + seq_printf(seq, "%-15s=%s\n", "post_state", + dpst_state_name_get(post->state)); + + seq_printf(seq, "%-15s=%d\n", "pre_get_sum", + get_sum_g(channel)); + seq_printf(seq, "%-15s=%d\n", "pre_put_sum", + get_sum_p(channel)); + dump_state_flag = 0; + return 0; +} + +static int seq_file_afbc_show(struct seq_file *seq, void *v) +{ + seq_puts(seq, "******dump VD2 AFBC********\n"); + seq_printf(seq, "VD2_AFBC_ENABLE 0x%x.\n", + dim_RDMA_RD(VD2_AFBC_ENABLE)); + seq_printf(seq, "VD2_AFBC_STAT 0x%x.\n", dim_RDMA_RD(VD2_AFBC_STAT)); + seq_printf(seq, "VD2_AFBCD1_MISC_CTRL 0x%x.\n", + dim_RDMA_RD(VD2_AFBCD1_MISC_CTRL)); + + seq_puts(seq, "******dump VD1 AFBC********\n"); + seq_printf(seq, "AFBC_ENABLE 0x%x.\n", dim_RDMA_RD(AFBC_ENABLE)); + seq_printf(seq, "AFBC_STAT 0x%x.\n", dim_RDMA_RD(AFBC_STAT)); + seq_printf(seq, "VD1_AFBCD0_MISC_CTRL 0x%x.\n", + dim_RDMA_RD(VD1_AFBCD0_MISC_CTRL)); + seq_puts(seq, "***************************\n"); + + seq_printf(seq, "VIU_MISC_CTRL0 0x%x.\n", dim_RDMA_RD(VIU_MISC_CTRL0)); + seq_printf(seq, "VIU_MISC_CTRL1 0x%x.\n", dim_RDMA_RD(VIU_MISC_CTRL1)); + seq_printf(seq, "VIUB_MISC_CTRL0 0x%x.\n", + dim_RDMA_RD(VIUB_MISC_CTRL0)); + + seq_printf(seq, "DI_PRE_CTRL bit8=%d,bit 28 =%d.\n", + dim_RDMA_RD_BITS(DI_PRE_CTRL, 8, 1), + dim_RDMA_RD_BITS(DI_PRE_CTRL, 28, 1)); + + return 0; +} + +/*2018-08-17 add debugfs*/ +#define DEFINE_SHOW_DI(__name) \ +static int __name ## _open(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, __name ## _show, inode->i_private); \ +} \ + \ +static const struct file_operations __name ## _fops = { \ + .owner = THIS_MODULE, \ + .open = __name ## _open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ +} + +DEFINE_SHOW_DI(seq_file_module_para); +/*DEFINE_SHOW_DI(seq_file_di_state);*/ +DEFINE_SHOW_DI(seq_file_dump_di_reg); +/*DEFINE_SHOW_DI(seq_file_dump_mif_size_state);*/ +DEFINE_SHOW_DI(seq_file_afbc); + +struct di_debugfs_files_t { + const char *name; + const umode_t mode; + const struct file_operations *fops; +}; + +static struct di_debugfs_files_t di_debugfs_files[] = { +/* {"state", S_IFREG | 0644, &seq_file_di_state_fops},*/ + {"dumpreg", S_IFREG | 0644, &seq_file_dump_di_reg_fops}, +/* {"dumpmif", S_IFREG | 0644, &seq_file_dump_mif_size_state_fops},*/ + {"dumpafbc", S_IFREG | 0644, &seq_file_afbc_fops}, + {"dumppara", S_IFREG | 0644, &seq_file_module_para_fops}, +}; + +void dim_debugfs_init(void) +{ + int i; + struct dentry *ent; + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (de_devp->dbg_root) + return; + + de_devp->dbg_root = debugfs_create_dir("di", NULL); + if (!de_devp->dbg_root) { + PR_ERR("can't create debugfs dir di\n"); + return; + } + + for (i = 0; i < ARRAY_SIZE(di_debugfs_files); i++) { + ent = debugfs_create_file(di_debugfs_files[i].name, + di_debugfs_files[i].mode, + de_devp->dbg_root, NULL, + di_debugfs_files[i].fops); + if (!ent) + PR_ERR("debugfs create failed\n"); + } +} + +void dim_debugfs_exit(void) +{ + struct di_dev_s *de_devp = get_dim_de_devp(); + + if (de_devp && de_devp->dbg_root) + debugfs_remove_recursive(de_devp->dbg_root); +} + +/*-----------------------*/ diff --git a/drivers/amlogic/media/di_multi/deinterlace_dbg.h b/drivers/amlogic/media/di_multi/deinterlace_dbg.h new file mode 100644 index 0000000..7aa2ed2 --- /dev/null +++ b/drivers/amlogic/media/di_multi/deinterlace_dbg.h @@ -0,0 +1,43 @@ +/* + * drivers/amlogic/media/di_multi/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. + * + */ + +#ifndef _DI_DBG_H +#define _DI_DBG_H +#include "deinterlace.h" + +void dim_parse_cmd_params(char *buf_orig, char **parm); +void dim_dump_pre_stru(struct di_pre_stru_s *ppre); +void dim_dump_post_stru(struct di_post_stru_s *di_post_stru_p); +void dim_dump_di_buf(struct di_buf_s *di_buf); +void dim_dump_pool(struct queue_s *q); +void dim_dump_vframe(vframe_t *vf); +void dim_print_di_buf(struct di_buf_s *di_buf, int format); +void dim_dump_pre_mif_state(void); +void dim_dump_post_mif_reg(void); +void dim_dump_buf_addr(struct di_buf_s *di_buf, unsigned int num); +void dim_dump_mif_size_state(struct di_pre_stru_s *pre, + struct di_post_stru_s *post); +void debug_device_files_add(struct device *dev); +void debug_device_files_del(struct device *dev); +void dim_debugfs_init(void); +void dim_debugfs_exit(void); +int dim_state_show(struct seq_file *seq, void *v, + unsigned int channel); +int dim_dump_mif_size_state_show(struct seq_file *seq, void *v, + unsigned int channel); + +#endif diff --git a/drivers/amlogic/media/di_multi/deinterlace_hw.c b/drivers/amlogic/media/di_multi/deinterlace_hw.c new file mode 100644 index 0000000..5fa6bfb --- /dev/null +++ b/drivers/amlogic/media/di_multi/deinterlace_hw.c @@ -0,0 +1,4236 @@ +/* + * drivers/amlogic/media/di_multi/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 +#include +#include "deinterlace.h" +#include "di_data_l.h" + +#include "deinterlace_hw.h" +#include "register.h" +#include "register_nr4.h" +#ifdef DET3D +#include "detect3d.h" +#endif +#include "di_api.h" +#include "di_reg_tab.h" +#include "di_prc.h" + +#include + +static unsigned int ctrl_regs[SKIP_CTRE_NUM]; + +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, int vskip_cnt); + +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, int vskip_cnt, int wr_en); + +static void set_di_if0_mif_g12(struct DI_MIF_s *mif, int urgent, + int hold_line, int vskip_cnt, int wr_en); + +static void ma_di_init(void) +{ + /* 420->422 chrome difference is large motion is large,flick */ + dim_DI_Wr(DI_MTN_1_CTRL4, 0x01800880); + dim_DI_Wr(DI_MTN_1_CTRL7, 0x0a800480); + /* mtn setting */ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) { + dim_DI_Wr_reg_bits(DI_MTN_CTRL, 1, 0, 1); + dim_DI_Wr(DI_MTN_1_CTRL1, 0x202015); + } else { + dim_DI_Wr(DI_MTN_1_CTRL1, 0xa0202015); + } + /* invert chan2 field num */ + dim_DI_Wr(DI_MTN_CTRL1, (1 << 17) | 2); + /* no invert chan2 field num from gxlx*/ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) + dim_DI_Wr(DI_MTN_CTRL1, 2); +} + +static void ei_hw_init(void) +{ + /* ei setting */ + dim_DI_Wr(DI_EI_CTRL0, 0x00ff0100); + dim_DI_Wr(DI_EI_CTRL1, 0x5a0a0f2d); + dim_DI_Wr(DI_EI_CTRL2, 0x050a0a5d); + dim_DI_Wr(DI_EI_CTRL3, 0x80000013); + if (is_meson_txlx_cpu()) { + dim_DI_Wr_reg_bits(DI_EI_DRT_CTRL, 1, 30, 1); + dim_DI_Wr_reg_bits(DI_EI_DRT_CTRL, 1, 31, 1); + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) { + dim_DI_Wr_reg_bits(DI_EI_DRT_CTRL_GXLX, 1, 30, 1); + dim_DI_Wr_reg_bits(DI_EI_DRT_CTRL_GXLX, 1, 31, 1); + } +} + +static void mc_di_param_init(void) +{ + dim_DI_Wr(MCDI_CHK_EDGE_GAIN_OFFST, 0x4f6124); + dim_DI_Wr(MCDI_LMV_RT, 0x7455); + dim_DI_Wr(MCDI_LMV_GAINTHD, 0x6014d409); + dim_DI_Wr(MCDI_REL_DET_LPF_MSK_22_30, 0x0a010001); + dim_DI_Wr(MCDI_REL_DET_LPF_MSK_31_34, 0x01010101); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + dim_DI_Wr_reg_bits(MCDI_REF_MV_NUM, 2, 0, 2); +} + +void dimh_init_field_mode(unsigned short height) +{ + dim_DI_Wr(DIPD_COMB_CTRL0, 0x02400210); + dim_DI_Wr(DIPD_COMB_CTRL1, 0x88080808); + dim_DI_Wr(DIPD_COMB_CTRL2, 0x41041008); + dim_DI_Wr(DIPD_COMB_CTRL3, 0x00008053); + dim_DI_Wr(DIPD_COMB_CTRL4, 0x20070002); + if (height > 288) + dim_DI_Wr(DIPD_COMB_CTRL5, 0x04041020); + else + dim_DI_Wr(DIPD_COMB_CTRL5, 0x04040804); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) + dim_DI_Wr(DIPD_COMB_CTRL6, 0x00107064); + dim_DI_Wr_reg_bits(DI_MC_32LVL0, 16, 0, 8); + dim_DI_Wr_reg_bits(DI_MC_22LVL0, 256, 0, 16); +} + +static void mc_pd22_check_irq(void) +{ + int cls_2_stl_thd = 1, cls_2_stl = 0; + int is_zmv = 0, no_gmv = 0; + int i, last_gmv, last_22_flg; + int cur_gmv, cur_22_flg; + unsigned int reg_val = 0; + + if (!dimp_get(eDI_MP_pd22_flg_calc_en)) + return; + + is_zmv = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 1, 1); + last_gmv = dim_RDMA_RD_BITS(MCDI_FIELD_MV, 0, 6); + last_gmv = last_gmv > 32 ? (32 - last_gmv) : last_gmv; + cur_gmv = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 2, 6); + cur_gmv = cur_gmv > 32 ? (32 - cur_gmv) : cur_gmv; + + cls_2_stl = abs(cur_gmv) <= cls_2_stl_thd; + no_gmv = (abs(cur_gmv) == 32 && (abs(last_gmv) <= cls_2_stl_thd)); + for (i = 0; i < 3; i++) { + last_22_flg = + dim_RDMA_RD_BITS(MCDI_PD_22_CHK_FLG_CNT, (24 + i), 1); + cur_22_flg = dim_RDMA_RD_BITS(MCDI_RO_PD_22_FLG, (24 + i), 1); + if ((is_zmv == 1 || cls_2_stl == 1 || no_gmv == 1) && + last_22_flg == 1 && cur_22_flg == 0) { + dim_RDMA_WR_BITS(MCDI_PD_22_CHK_FLG_CNT, + last_22_flg, (24 + i), 1); + reg_val = dim_RDMA_RD_BITS(MCDI_PD22_CHK_THD_RT, + 0, 5) - 1; + dim_RDMA_WR_BITS(MCDI_PD_22_CHK_FLG_CNT, + reg_val, i * 8, 8); + } else { + dim_RDMA_WR_BITS(MCDI_PD_22_CHK_FLG_CNT, + cur_22_flg, (24 + i), 1); + reg_val = + dim_RDMA_RD_BITS(MCDI_RO_PD_22_FLG, i * 8, 8); + dim_RDMA_WR_BITS(MCDI_PD_22_CHK_FLG_CNT, + reg_val, i * 8, 8); + } + } +} + +void dimh_mc_pre_mv_irq(void) +{ + unsigned int val1; + + if (dimp_get(eDI_MP_pd22_flg_calc_en) && is_meson_gxlx_cpu()) { + mc_pd22_check_irq(); + } else { + val1 = dim_RDMA_RD(MCDI_RO_PD_22_FLG); + dim_RDMA_WR(MCDI_PD_22_CHK_FLG_CNT, val1); + } + + val1 = dim_RDMA_RD_BITS(MCDI_RO_HIGH_VERT_FRQ_FLG, 0, 1); + dim_RDMA_WR_BITS(MCDI_FIELD_HVF_PRDX_CNT, val1, 0, 1); + val1 = dim_RDMA_RD_BITS(MCDI_RO_HIGH_VERT_FRQ_FLG, 1, 2); + dim_RDMA_WR_BITS(MCDI_FIELD_HVF_PRDX_CNT, val1, 2, 2); + val1 = dim_RDMA_RD_BITS(MCDI_RO_HIGH_VERT_FRQ_FLG, 8, 8); + dim_RDMA_WR_BITS(MCDI_FIELD_HVF_PRDX_CNT, val1, 8, 8); + val1 = dim_RDMA_RD_BITS(MCDI_RO_MOTION_PARADOX_FLG, 0, 16); + dim_RDMA_WR_BITS(MCDI_FIELD_HVF_PRDX_CNT, val1, 16, 16); + + val1 = dim_RDMA_RD_BITS(MCDI_RO_RPT_MV, 0, 6); + if (val1 == 32) { + val1 = 0; + dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 15, 1); + } else { + dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 15, 1); + } + + dim_RDMA_WR_BITS(MCDI_FIELD_MV, val1, 8, 6); + + val1 = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 0, 1); + dim_RDMA_WR_BITS(MCDI_FIELD_MV, val1, 14, 1); + + val1 = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 8, 8); + dim_RDMA_WR_BITS(MCDI_FIELD_MV, val1, 16, 8); + + val1 = dim_RDMA_RD_BITS(MCDI_RO_GMV_LOCK_FLG, 2, 6); + if (val1 == 32) { + val1 = 0; + dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 14, 1); + } else { + dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 14, 1); + } + dim_RDMA_WR_BITS(MCDI_FIELD_MV, val1, 0, 6); + + val1 = dim_RDMA_RD(MCDI_FIELD_LUMA_AVG_SUM_1); + dim_RDMA_WR(MCDI_FIELD_LUMA_AVG_SUM_0, val1); + + val1 = dim_RDMA_RD(MCDI_RO_FLD_LUMA_AVG_SUM); + dim_RDMA_WR(MCDI_FIELD_LUMA_AVG_SUM_1, val1); +} + +static void lmvs_init(struct mcinfo_lmv_s *lmvs, unsigned short lmv) +{ + lmvs->lock_flag = (lmv >> 14) & 3; + lmvs->lmv = (lmv >> 8) & 63; + lmvs->lmv = lmvs->lmv > 32 ? (32 - lmvs->lmv) : lmvs->lmv; + lmvs->lock_cnt = (lmv & 255); +} + +void dimh_calc_lmv_init(void) +{ + if (dimp_get(eDI_MP_lmv_lock_win_en)) { + dim_RDMA_WR_BITS(MCDI_REL_DET_LMV_DIF_CHK, 3, 12, 2); + dim_RDMA_WR_BITS(MCDI_LMVLCKSTEXT_1, 3, 30, 2); + } else { + dim_RDMA_WR_BITS(MCDI_REL_DET_LMV_DIF_CHK, 0, 12, 2); + dim_RDMA_WR_BITS(MCDI_LMVLCKSTEXT_1, 0, 30, 2); + } +} + +static struct mcinfo_lmv_s lines_mv[540]; + +void dimh_calc_lmv_base_mcinfo(unsigned int vf_height, unsigned long mcinfo_adr, + unsigned int mcinfo_size) +{ + unsigned short i, top_str, bot_str, top_end, bot_end, j = 0; + unsigned short *mcinfo_vadr = NULL, lck_num; + unsigned short flg_m1 = 0, flg_i = 0, nLmvLckSt = 0; + unsigned short lmv_lckstext[3] = {0, 0, 0}, nLmvLckEd; + unsigned short lmv_lckedext[3] = {0, 0, 0}, nLmvLckNum; + bool bflg_vmap = false; + u8 *tmp; + + /*mcinfo_vadr = (unsigned short *)phys_to_virt(mcinfo_adr);*/ + + if (!dimp_get(eDI_MP_lmv_lock_win_en)) + return; + + tmp = dim_vmap(mcinfo_adr, mcinfo_size, &bflg_vmap); + if (!tmp) { + dim_print("err:dim_vmap failed\n"); + return; + } + mcinfo_vadr = (unsigned short *)tmp; + + for (i = 0; i < (vf_height >> 1); i++) { + lmvs_init(&lines_mv[i], *(mcinfo_vadr + i)); + j = i + (vf_height >> 1); + lmvs_init(&lines_mv[j], *(mcinfo_vadr + i + 272)); + if (dimp_get(eDI_MP_pr_mcinfo_cnt) && j < (vf_height - 10) && + j > (vf_height - dimp_get(eDI_MP_offset_lmv))) { + pr_info("MCINFO[%u]=0x%x\t", j, + *(mcinfo_vadr + i + 272)); + if (i % 16 == 0) + pr_info("\n"); + } + } + if (bflg_vmap) + dim_unmap_phyaddr(tmp); + + /*pr_mcinfo_cnt ? pr_mcinfo_cnt-- : (pr_mcinfo_cnt = 0);*/ + dimp_get(eDI_MP_pr_mcinfo_cnt) ? + dimp_dec(eDI_MP_pr_mcinfo_cnt) : + dimp_set(eDI_MP_pr_mcinfo_cnt, 0); + + top_str = 0; + top_end = dimp_get(eDI_MP_offset_lmv); + i = top_str; + j = 0; + lck_num = Rd_reg_bits(MCDI_LMVLCKSTEXT_1, 16, 12); + + while (i < top_end) { + flg_m1 = (i == top_str) ? 0 : + (lines_mv[i - 1].lock_flag > 0); + flg_i = (i == top_end - 1) ? 0 : + lines_mv[i].lock_flag > 0; + if (!flg_m1 && flg_i) { + #if 0 + nLmvLckSt = (j == 0) ? i : ((i < (lmv_lckedext[j - 1] + + dimp_get(eDI_MP_lmv_dist))) ? + lmv_lckstext[j - 1] : i); + #else + if (j == 0) { + nLmvLckSt = i; + } else { + if (i < (lmv_lckedext[j - 1] + + dimp_get(eDI_MP_lmv_dist))) + nLmvLckSt = lmv_lckstext[j - 1]; + else + nLmvLckSt = i; + } + #endif + j = (nLmvLckSt != i) ? (j - 1) : j; + } else if (flg_m1 && !flg_i) { + nLmvLckEd = i; + nLmvLckNum = (nLmvLckEd - nLmvLckSt + 1); + if (nLmvLckNum >= lck_num) { + lmv_lckstext[j] = nLmvLckSt; + lmv_lckedext[j] = nLmvLckEd; + j++; + } + } + i++; + if (j > 2) + break; + } + + bot_str = vf_height - dimp_get(eDI_MP_offset_lmv) - 1; + bot_end = vf_height; + i = bot_str; + while (i < bot_end && j < 3) { + flg_m1 = (i == bot_str) ? 0 : + (lines_mv[i - 1].lock_flag > 0); + flg_i = (i == bot_end - 1) ? 0 : + lines_mv[i].lock_flag > 0; + if (!flg_m1 && flg_i) { + nLmvLckSt = (j == 0) ? i : ((i < (lmv_lckedext[j - 1] + + dimp_get(eDI_MP_lmv_dist))) ? + lmv_lckstext[j - 1] : i); + j = (nLmvLckSt != i) ? (j - 1) : j; + } else if (flg_m1 && !flg_i) { + nLmvLckEd = i; + nLmvLckNum = (nLmvLckEd - nLmvLckSt + 1); + if (nLmvLckNum >= lck_num) { + lmv_lckstext[j] = nLmvLckSt; + lmv_lckedext[j] = nLmvLckEd; + j++; + } + } + i++; + if (j > 2) + break; + } + + Wr(MCDI_LMVLCKSTEXT_0, lmv_lckstext[1] << 16 | lmv_lckstext[0]); + Wr_reg_bits(MCDI_LMVLCKSTEXT_1, lmv_lckstext[2], 0, 12); + Wr(MCDI_LMVLCKEDEXT_0, lmv_lckedext[1] << 16 | lmv_lckedext[0]); + Wr(MCDI_LMVLCKEDEXT_1, lmv_lckedext[2]); +} + +/* + * config pre hold ratio & mif request block len + * pass_ratio = (pass_cnt + 1)/(pass_cnt + 1 + hold_cnt + 1) + */ +static void pre_hold_block_mode_config(void) +{ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + dim_DI_Wr(DI_PRE_HOLD, 0); + /* go field after 2 lines */ + dim_DI_Wr(DI_PRE_GL_CTRL, + (0x80000000 | dimp_get(eDI_MP_line_num_pre_frst))); + } else if (is_meson_txlx_cpu()) { + /* setup pre process ratio to 66.6%*/ + dim_DI_Wr(DI_PRE_HOLD, (1 << 31) | (1 << 16) | 3); + /* block len, after block insert null req to balance reqs */ + dim_DI_Wr_reg_bits(DI_INP_GEN_REG3, 0, 4, 3); + dim_DI_Wr_reg_bits(DI_MEM_GEN_REG3, 0, 4, 3); + dim_DI_Wr_reg_bits(DI_CHAN2_GEN_REG3, 0, 4, 3); + dim_DI_Wr_reg_bits(DI_IF1_GEN_REG3, 0, 4, 3); + dim_DI_Wr_reg_bits(DI_IF2_GEN_REG3, 0, 4, 3); + dim_DI_Wr_reg_bits(VD1_IF0_GEN_REG3, 0, 4, 3); + } else { + dim_DI_Wr(DI_PRE_HOLD, (1 << 31) | (31 << 16) | 31); + } +} + +/* + * ctrl or size related regs configured + * in software base on real size and condition + */ +static void set_skip_ctrl_size_regs(void) +{ + ctrl_regs[0] = DI_CLKG_CTRL; + ctrl_regs[1] = DI_MTN_1_CTRL1; + ctrl_regs[2] = MCDI_MOTINEN; + ctrl_regs[3] = MCDI_CTRL_MODE; + ctrl_regs[4] = MCDI_MC_CRTL; + ctrl_regs[5] = MCDI_PD_22_CHK_WND0_X; + ctrl_regs[6] = MCDI_PD_22_CHK_WND0_Y; + ctrl_regs[7] = MCDI_PD_22_CHK_WND1_X; + ctrl_regs[8] = MCDI_PD_22_CHK_WND1_Y; + ctrl_regs[9] = NR4_MCNR_LUMA_STAT_LIMTX; + ctrl_regs[10] = NR4_MCNR_LUMA_STAT_LIMTY; + ctrl_regs[11] = NR4_NM_X_CFG; + ctrl_regs[12] = NR4_NM_Y_CFG; +} + +void dim_hw_init_reg(void) +{ + unsigned short fifo_size_post = 0x120;/*feijun 08-02*/ + + if (is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_sm1_cpu()) { + dim_DI_Wr(DI_IF1_LUMA_FIFO_SIZE, fifo_size_post); + /* 17f2 is DI_IF1_luma_fifo_size */ + dim_DI_Wr(DI_IF2_LUMA_FIFO_SIZE, fifo_size_post); + dim_DI_Wr(DI_IF0_LUMA_FIFO_SIZE, fifo_size_post); + } + + PR_INF("%s, 0x%x\n", __func__, dim_RDMA_RD(DI_IF0_LUMA_FIFO_SIZE)); +} + +void dimh_hw_init(bool pd_enable, bool mc_enable) +{ + unsigned short fifo_size_vpp = 0xc0; + unsigned short fifo_size_di = 0xc0; + + diext_clk_b_sw(true); + if (is_meson_txlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_sm1_cpu() || + is_meson_tm2_cpu()) + dim_top_gate_control(true, true); + else if (is_meson_gxl_cpu() || + is_meson_gxm_cpu() || + is_meson_gxlx_cpu()) + dim_DI_Wr(DI_CLKG_CTRL, 0xffff0001); + else + dim_DI_Wr(DI_CLKG_CTRL, 0x1); /* di no clock gate */ + + if (is_meson_txl_cpu() || + is_meson_txlx_cpu() || + is_meson_gxlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_sm1_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_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; + } + + /*enable lock win, suggestion from vlsi zheng.bao*/ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dimp_set(eDI_MP_lmv_lock_win_en, 0);/*lmv_lock_win_en = 0;*/ + + dim_DI_Wr(VD1_IF0_LUMA_FIFO_SIZE, fifo_size_vpp); + dim_DI_Wr(VD2_IF0_LUMA_FIFO_SIZE, fifo_size_vpp); + /* 1a83 is vd2_if0_luma_fifo_size */ + dim_DI_Wr(DI_INP_LUMA_FIFO_SIZE, fifo_size_di); + /* 17d8 is DI_INP_luma_fifo_size */ + dim_DI_Wr(DI_MEM_LUMA_FIFO_SIZE, fifo_size_di); + /* 17e5 is DI_MEM_luma_fifo_size */ + dim_DI_Wr(DI_IF1_LUMA_FIFO_SIZE, fifo_size_di); + /* 17f2 is DI_IF1_luma_fifo_size */ + dim_DI_Wr(DI_IF2_LUMA_FIFO_SIZE, fifo_size_di); + /* 201a is if2 fifo size */ + dim_DI_Wr(DI_CHAN2_LUMA_FIFO_SIZE, fifo_size_di); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + dim_DI_Wr(DI_IF0_LUMA_FIFO_SIZE, fifo_size_di); + dim_DI_Wr(DI_ARB_CTRL, 0); + } else { + /* enable di all arb */ + dim_DI_Wr_reg_bits(DI_ARB_CTRL, 0xf0f, 0, 16); + } + /* 17b3 is DI_chan2_luma_fifo_size */ + if (is_meson_txlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_sm1_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu()) { + dim_pre_gate_control(true, true); + dim_post_gate_control(true); + } + + pre_hold_block_mode_config(); + set_skip_ctrl_size_regs(); + ma_di_init(); + ei_hw_init(); + get_ops_nr()->nr_hw_init(); + if (pd_enable) + dimh_init_field_mode(288); + + if (mc_enable) + mc_di_param_init(); + if (is_meson_txlx_cpu() || + is_meson_txhd_cpu() || + is_meson_g12a_cpu() || + is_meson_sm1_cpu() || + is_meson_g12b_cpu() || + is_meson_tl1_cpu() || + is_meson_tm2_cpu()) { + dim_pre_gate_control(false, true); + dim_post_gate_control(false); + dim_top_gate_control(false, false); + } else if (is_meson_txl_cpu() || is_meson_gxlx_cpu()) { + /* di clock div enable for pq load */ + dim_DI_Wr(DI_CLKG_CTRL, 0x80000000); + } else { + dim_DI_Wr(DI_CLKG_CTRL, 0x2); /* di clock gate all */ + } + + diext_clk_b_sw(false); + + /*move from prob*/ + dim_DI_Wr_reg_bits(MCDI_MC_CRTL, 0, 0, 1); +} + +void dimh_hw_uninit(void) +{ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) + get_ops_nr()->nr_gate_control(false); +} + +/* + * mtn wr mif, contprd mif, contp2rd mif, + * contwr mif config + */ +static void set_ma_pre_mif(struct DI_SIM_MIF_s *mtnwr_mif, + struct DI_SIM_MIF_s *contprd_mif, + struct DI_SIM_MIF_s *contp2rd_mif, + struct DI_SIM_MIF_s *contwr_mif, + unsigned short urgent) +{ + /* current field mtn canvas index. */ + dim_RDMA_WR(DI_MTNWR_X, + (mtnwr_mif->start_x << 16) | + (mtnwr_mif->end_x)); + dim_RDMA_WR(DI_MTNWR_Y, + (mtnwr_mif->start_y << 16) | + (mtnwr_mif->end_y)); + dim_RDMA_WR(DI_MTNWR_CTRL, + mtnwr_mif->canvas_num | + (urgent << 8)); /* urgent. */ + + dim_RDMA_WR(DI_CONTPRD_X, + (contprd_mif->start_x << 16) | + (contprd_mif->end_x)); + dim_RDMA_WR(DI_CONTPRD_Y, + (contprd_mif->start_y << 16) | + (contprd_mif->end_y)); + dim_RDMA_WR(DI_CONTP2RD_X, + (contp2rd_mif->start_x << 16) | + (contp2rd_mif->end_x)); + dim_RDMA_WR(DI_CONTP2RD_Y, + (contp2rd_mif->start_y << 16) | + (contp2rd_mif->end_y)); + dim_RDMA_WR(DI_CONTRD_CTRL, + (contprd_mif->canvas_num << 8) | + (urgent << 16) | /* urgent */ + contp2rd_mif->canvas_num); + + dim_RDMA_WR(DI_CONTWR_X, + (contwr_mif->start_x << 16) | + (contwr_mif->end_x)); + dim_RDMA_WR(DI_CONTWR_Y, + (contwr_mif->start_y << 16) | + (contwr_mif->end_y)); + dim_RDMA_WR(DI_CONTWR_CTRL, + contwr_mif->canvas_num | + (urgent << 8));/* urgent. */ +} + +static void set_ma_pre_mif_g12(struct DI_SIM_MIF_s *mtnwr_mif, + struct DI_SIM_MIF_s *contprd_mif, + struct DI_SIM_MIF_s *contp2rd_mif, + struct DI_SIM_MIF_s *contwr_mif, + unsigned short urgent) +{ + dim_RDMA_WR_BITS(CONTRD_SCOPE_X, contprd_mif->start_x, 0, 13); + dim_RDMA_WR_BITS(CONTRD_SCOPE_X, contprd_mif->end_x, 16, 13); + dim_RDMA_WR_BITS(CONTRD_SCOPE_Y, contprd_mif->start_y, 0, 13); + dim_RDMA_WR_BITS(CONTRD_SCOPE_Y, contprd_mif->end_y, 16, 13); + dim_RDMA_WR_BITS(CONTRD_CTRL1, contprd_mif->canvas_num, 16, 8); + dim_RDMA_WR_BITS(CONTRD_CTRL1, 2, 8, 2); + dim_RDMA_WR_BITS(CONTRD_CTRL1, 0, 0, 3); + + dim_RDMA_WR_BITS(CONT2RD_SCOPE_X, contp2rd_mif->start_x, 0, 13); + dim_RDMA_WR_BITS(CONT2RD_SCOPE_X, contp2rd_mif->end_x, 16, 13); + dim_RDMA_WR_BITS(CONT2RD_SCOPE_Y, contp2rd_mif->start_y, 0, 13); + dim_RDMA_WR_BITS(CONT2RD_SCOPE_Y, contp2rd_mif->end_y, 16, 13); + dim_RDMA_WR_BITS(CONT2RD_CTRL1, contp2rd_mif->canvas_num, 16, 8); + dim_RDMA_WR_BITS(CONT2RD_CTRL1, 2, 8, 2); + dim_RDMA_WR_BITS(CONT2RD_CTRL1, 0, 0, 3); + + /* current field mtn canvas index. */ + dim_RDMA_WR_BITS(MTNWR_X, mtnwr_mif->start_x, 16, 13); + dim_RDMA_WR_BITS(MTNWR_X, mtnwr_mif->end_x, 0, 13); + dim_RDMA_WR_BITS(MTNWR_X, 2, 30, 2); + dim_RDMA_WR_BITS(MTNWR_Y, mtnwr_mif->start_y, 16, 13); + dim_RDMA_WR_BITS(MTNWR_Y, mtnwr_mif->end_y, 0, 13); + dim_RDMA_WR_BITS(MTNWR_CTRL, mtnwr_mif->canvas_num, 0, 8); + dim_RDMA_WR_BITS(MTNWR_CAN_SIZE, + (mtnwr_mif->end_y - mtnwr_mif->start_y), 0, 13); + dim_RDMA_WR_BITS(MTNWR_CAN_SIZE, + (mtnwr_mif->end_x - mtnwr_mif->start_x), 16, 13); + + dim_RDMA_WR_BITS(CONTWR_X, contwr_mif->start_x, 16, 13); + dim_RDMA_WR_BITS(CONTWR_X, contwr_mif->end_x, 0, 13); + dim_RDMA_WR_BITS(CONTWR_X, 2, 30, 2); + dim_RDMA_WR_BITS(CONTWR_Y, contwr_mif->start_y, 16, 13); + dim_RDMA_WR_BITS(CONTWR_Y, contwr_mif->end_y, 0, 13); + dim_RDMA_WR_BITS(CONTWR_CTRL, contwr_mif->canvas_num, 0, 8); + dim_RDMA_WR_BITS(CONTWR_CAN_SIZE, + (contwr_mif->end_y - contwr_mif->start_y), 0, 13); + dim_RDMA_WR_BITS(CONTWR_CAN_SIZE, + (contwr_mif->end_x - contwr_mif->start_x), 16, 13); +} + +static void set_di_nrwr_mif(struct DI_SIM_MIF_s *nrwr_mif, + unsigned short urgent) +{ + dim_RDMA_WR_BITS(DI_NRWR_X, nrwr_mif->end_x, 0, 14); + dim_RDMA_WR_BITS(DI_NRWR_X, nrwr_mif->start_x, 16, 14); + dim_RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->start_y, 16, 13); + dim_RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->end_y, 0, 13); + /* wr ext en from gxtvbb */ + dim_RDMA_WR_BITS(DI_NRWR_Y, 1, 15, 1); + dim_RDMA_WR_BITS(DI_NRWR_Y, 3, 30, 2); + + dim_RDMA_WR_BITS(DI_NRWR_Y, nrwr_mif->bit_mode & 0x1, 14, 1); + + /*fix 1080i crash when di work on low speed*/ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL) && + ((nrwr_mif->bit_mode & 0x3) == 0x3)) { + dim_RDMA_WR(DI_NRWR_CTRL, + nrwr_mif->canvas_num | + (urgent << 16) | + 3 << 22 | + 1 << 24 | + 2 << 26 | /*burst_lim 1->2 2->4*/ + 1 << 30); /* urgent bit 16 */ + } else { + dim_RDMA_WR(DI_NRWR_CTRL, + nrwr_mif->canvas_num | + (urgent << 16) | + 1 << 24 | + 2 << 26 | /*burst_lim 1->2 2->4*/ + 1 << 30); /* urgent bit 16 */ + } +} + +void dimh_interrupt_ctrl(unsigned char ma_en, + unsigned char det3d_en, unsigned char nrds_en, + unsigned char post_wr, unsigned char mc_en) +{ + dim_RDMA_WR_BITS(DI_INTR_CTRL, ma_en ? 0 : 1, 17, 1); + dim_RDMA_WR_BITS(DI_INTR_CTRL, ma_en ? 0 : 1, 20, 1); + dim_RDMA_WR_BITS(DI_INTR_CTRL, mc_en ? 0 : 3, 22, 2); + /* enable nr wr int */ + dim_RDMA_WR_BITS(DI_INTR_CTRL, 0, 16, 1); + dim_RDMA_WR_BITS(DI_INTR_CTRL, post_wr ? 0 : 1, 18, 1); + /* mask me interrupt hit abnormal */ + dim_RDMA_WR_BITS(DI_INTR_CTRL, 1, 21, 1); + /* mask hist interrupt */ + dim_RDMA_WR_BITS(DI_INTR_CTRL, 1, 19, 1); + dim_RDMA_WR_BITS(DI_INTR_CTRL, det3d_en ? 0 : 1, 24, 1); + dim_RDMA_WR_BITS(DI_INTR_CTRL, nrds_en ? 0 : 1, 25, 1); + /* clean all pending interrupt bits */ + dim_RDMA_WR_BITS(DI_INTR_CTRL, 0xffff, 0, 16); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dim_RDMA_WR_BITS(DI_INTR_CTRL, 3, 30, 2); + else + dim_RDMA_WR_BITS(DI_INTR_CTRL, 0, 30, 2); +} + +void dimh_int_ctr(unsigned int set_mod, unsigned char ma_en, + unsigned char det3d_en, unsigned char nrds_en, + unsigned char post_wr, unsigned char mc_en) +{ + static unsigned char lst_ma, lst_det3d, lst_nrds, lst_pw, lst_mc; + + if (set_mod == 0) { + /*int:*/ + lst_ma = 1; + lst_det3d = 0; + lst_nrds = 1; + lst_pw = 1; + lst_mc = 1; + dimh_interrupt_ctrl(lst_ma, + lst_det3d, + lst_nrds, + lst_pw, + lst_mc); + return; + } + + if (ma_en != lst_ma) { + dim_RDMA_WR_BITS(DI_INTR_CTRL, ma_en ? 0 : 1, 17, 1); + dim_RDMA_WR_BITS(DI_INTR_CTRL, ma_en ? 0 : 1, 20, 1); + lst_ma = ma_en; + } + if (mc_en != lst_mc) { + dim_RDMA_WR_BITS(DI_INTR_CTRL, mc_en ? 0 : 3, 22, 2); + lst_mc = mc_en; + } + + if (post_wr != lst_pw) { + dim_RDMA_WR_BITS(DI_INTR_CTRL, post_wr ? 0 : 1, 18, 1); + lst_pw = post_wr; + } + + if (det3d_en != lst_det3d) { + dim_RDMA_WR_BITS(DI_INTR_CTRL, det3d_en ? 0 : 1, 24, 1); + lst_det3d = det3d_en; + } + + if (nrds_en != lst_nrds) { + dim_RDMA_WR_BITS(DI_INTR_CTRL, nrds_en ? 0 : 1, 25, 1); + lst_nrds = nrds_en; + } +} + +void dimh_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, + struct DI_SIM_MIF_s *di_contp2rd_mif, + struct DI_SIM_MIF_s *di_contprd_mif, + struct DI_SIM_MIF_s *di_contwr_mif, + unsigned char madi_en, unsigned char pre_field_num, + unsigned char pre_vdin_link) +{ + bool mem_bypass = false, chan2_disable = false; + unsigned short nrwr_hsize = 0, nrwr_vsize = 0; + unsigned short chan2_hsize = 0, chan2_vsize = 0; + unsigned short mem_hsize = 0, mem_vsize = 0; + + set_di_inp_mif(di_inp_mif, + dimp_get(eDI_MP_pre_urgent), + dimp_get(eDI_MP_pre_hold_line)); + set_di_nrwr_mif(di_nrwr_mif, + dimp_get(eDI_MP_pre_urgent)); + set_di_mem_mif(di_mem_mif, + dimp_get(eDI_MP_pre_urgent), + dimp_get(eDI_MP_pre_hold_line)); + set_di_chan2_mif(di_chan2_mif, + dimp_get(eDI_MP_pre_urgent), + dimp_get(eDI_MP_pre_hold_line)); + + nrwr_hsize = di_nrwr_mif->end_x - + di_nrwr_mif->start_x + 1; + nrwr_vsize = di_nrwr_mif->end_y - + di_nrwr_mif->start_y + 1; + chan2_hsize = di_chan2_mif->luma_x_end0 - + di_chan2_mif->luma_x_start0 + 1; + chan2_vsize = di_chan2_mif->luma_y_end0 - + di_chan2_mif->luma_y_start0 + 1; + mem_hsize = di_mem_mif->luma_x_end0 - + di_mem_mif->luma_x_start0 + 1; + mem_vsize = di_mem_mif->luma_y_end0 - + di_mem_mif->luma_y_start0 + 1; + if ((chan2_hsize != nrwr_hsize) || (chan2_vsize != nrwr_vsize)) + chan2_disable = true; + if ((mem_hsize != nrwr_hsize) || (mem_vsize != nrwr_vsize)) + mem_bypass = true; + /* + * enable&disable contwr txt + */ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) + dim_RDMA_WR_BITS(DI_MTN_CTRL, madi_en ? 5 : 0, 29, 3); + else + dim_RDMA_WR_BITS(DI_MTN_1_CTRL1, madi_en ? 5 : 0, 29, 3); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (madi_en) { + set_ma_pre_mif_g12(di_mtnwr_mif, + di_contprd_mif, + di_contp2rd_mif, + di_contwr_mif, + dimp_get(eDI_MP_pre_urgent)); + } else { + chan2_disable = true; + } + dim_RDMA_WR_BITS(DI_PRE_GL_THD, + dimp_get(eDI_MP_pre_hold_line), 16, 6); + if (dimp_get(eDI_MP_pre_ctrl)) + dim_RDMA_WR_BITS(DI_PRE_CTRL, + dimp_get(eDI_MP_pre_ctrl), 0, 29); + else + dim_RDMA_WR(DI_PRE_CTRL, + 1 | /* nr wr en */ + (madi_en << 1) | /* mtn en */ + (madi_en << 2) | /* check3:2pulldown*/ + (madi_en << 3) | /* check2:2pulldown*/ + (1 << 4) | + (madi_en << 5) | /*hist check enable*/ + /* hist check use chan2. */ + (madi_en << 6) | + /*hist check use data before noise reduction.*/ + ((chan2_disable ? 0 : 1) << 8) | + /* chan 2 enable for 2:2 pull down check.*/ + /* line buffer 2 enable */ + ((chan2_disable ? 0 : 1) << 9) | + (0 << 10) | /* pre drop first. */ + (1 << 11) | /* nrds mif enable */ + (0 << 12) | /* pre viu link */ + (pre_vdin_link << 13) | + /* pre go line link */ + (pre_vdin_link << 14) | + (1 << 21) | /*invertNRfield num*/ + (1 << 22) | /* MTN after NR. */ + (0 << 25) | /* contrd en */ + ((mem_bypass ? 1 : 0) << 28) | + pre_field_num << 29); + } else { + if (madi_en) { + set_ma_pre_mif(di_mtnwr_mif, + di_contprd_mif, + di_contp2rd_mif, + di_contwr_mif, + dimp_get(eDI_MP_pre_urgent)); + } + dim_RDMA_WR(DI_PRE_CTRL, + 1 /* nr enable */ + | (madi_en << 1) /* mtn_en */ + | (madi_en << 2) /* check 3:2 pulldown */ + | (madi_en << 3) /* check 2:2 pulldown */ + | (1 << 4) + | (madi_en << 5) /* hist check enable */ + | (1 << 6) /* hist check use chan2. */ + | (0 << 7) + /* hist check use data before noise reduction. */ + | (madi_en << 8) + /* chan 2 enable for 2:2 pull down check.*/ + | (madi_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 */ + | (dimp_get(eDI_MP_pre_hold_line) << 16) + /* pre hold line number */ + | (1 << 22) /* MTN after NR. */ + | (madi_en << 25) /* contrd en */ + | (pre_field_num << 29) /* pre field number.*/ + ); + } +} + +/* + * after g12a, framereset will not reset simple + * wr mif of pre such as mtn&cont&mv&mcinfo wr + */ +static const unsigned int reg_AFBC[AFBC_DEC_NUB][AFBC_REG_INDEX_NUB] = { + { + AFBC_ENABLE, + AFBC_MODE, + AFBC_SIZE_IN, + AFBC_DEC_DEF_COLOR, + AFBC_CONV_CTRL, + AFBC_LBUF_DEPTH, + AFBC_HEAD_BADDR, + AFBC_BODY_BADDR, + AFBC_SIZE_OUT, + AFBC_OUT_YSCOPE, + AFBC_STAT, + AFBC_VD_CFMT_CTRL, + AFBC_VD_CFMT_W, + AFBC_MIF_HOR_SCOPE, + AFBC_MIF_VER_SCOPE, + AFBC_PIXEL_HOR_SCOPE, + AFBC_PIXEL_VER_SCOPE, + AFBC_VD_CFMT_H, + }, + { + VD2_AFBC_ENABLE, + VD2_AFBC_MODE, + VD2_AFBC_SIZE_IN, + VD2_AFBC_DEC_DEF_COLOR, + VD2_AFBC_CONV_CTRL, + VD2_AFBC_LBUF_DEPTH, + VD2_AFBC_HEAD_BADDR, + VD2_AFBC_BODY_BADDR, + VD2_AFBC_OUT_XSCOPE, + VD2_AFBC_OUT_YSCOPE, + VD2_AFBC_STAT, + VD2_AFBC_VD_CFMT_CTRL, + VD2_AFBC_VD_CFMT_W, + VD2_AFBC_MIF_HOR_SCOPE, + VD2_AFBC_MIF_VER_SCOPE, + VD2_AFBC_PIXEL_HOR_SCOPE, + VD2_AFBC_PIXEL_VER_SCOPE, + VD2_AFBC_VD_CFMT_H, + + }, + +}; + +#define AFBC_DEC_SEL (eAFBC_DEC1) + +static enum eAFBC_DEC afbc_get_decnub(void) +{ + enum eAFBC_DEC sel_dec = eAFBC_DEC0; + + if (is_meson_gxl_cpu()) + sel_dec = eAFBC_DEC0; + else if (is_meson_txlx_cpu()) + sel_dec = eAFBC_DEC1; + else if (is_meson_g12a_cpu()) + sel_dec = AFBC_DEC_SEL; + /* TL1 only have AFBC0 */ + else if (is_meson_tl1_cpu()) + sel_dec = eAFBC_DEC0; + return sel_dec; +} + +static const unsigned int *afbc_get_regbase(void) +{ + return ®_AFBC[afbc_get_decnub()][0]; +} + +bool dimh_afbc_is_supported(void) +{ + bool ret = false; + + /*currently support txlx and g12a*/ + if (is_meson_txlx_cpu() || + is_meson_g12a_cpu() + /*|| is_meson_tl1_cpu()*/) + ret = false; + return ret; +} + +static void afbc_sw_trig(bool on); + +void dimh_enable_afbc_input(struct vframe_s *vf) +{ + unsigned int r, u, v, w_aligned, h_aligned; + unsigned int out_height = 0; + unsigned int vfmt_rpt_first = 1, vt_ini_phase = 0; + const unsigned int *reg = afbc_get_regbase(); + + if (!dimh_afbc_is_supported()) + return; + + if ((vf->type & VIDTYPE_COMPRESS)) { + /* only reg for the first time*/ + dimh_afbc_reg_sw(true); + afbc_sw_trig(true); + } else { + afbc_sw_trig(false); + return; + } + w_aligned = round_up((vf->width - 1), 32); + h_aligned = round_up((vf->height - 1), 4); + r = (3 << 24) | + (10 << 16) | + (1 << 14) | /*burst1 1*/ + (vf->bitdepth & BITDEPTH_MASK); + if (vf->bitdepth & BITDEPTH_SAVING_MODE) + r |= (1 << 28); /* mem_saving_mode */ + if (vf->type & VIDTYPE_SCATTER) + r |= (1 << 29); + out_height = h_aligned; + if ((vf->type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) { + r |= 0x40; + vt_ini_phase = 0xc; + out_height = h_aligned >> 1; + } else if ((vf->type & VIDTYPE_TYPEMASK) == + VIDTYPE_INTERLACE_BOTTOM) { + r |= 0x80; + vt_ini_phase = 0x4; + vfmt_rpt_first = 0; + out_height = h_aligned >> 1; + } + dim_RDMA_WR(reg[eAFBC_MODE], r); + r = 0x100; + /* TL1 add bit[13:12]: fmt_mode; 0:yuv444; 1:yuv422; 2:yuv420 + * di does not support yuv444, so for fmt yuv444 di will bypass+ + */ + if (is_meson_tl1_cpu()) { + if (vf->type & VIDTYPE_VIU_444) + r |= (0 << 12); + else if (vf->type & VIDTYPE_VIU_422) + r |= (1 << 12); + else + r |= (2 << 12); + } + dim_RDMA_WR(reg[eAFBC_CONV_CTRL], r); + u = (vf->bitdepth >> (BITDEPTH_U_SHIFT)) & 0x3; + v = (vf->bitdepth >> (BITDEPTH_V_SHIFT)) & 0x3; + dim_RDMA_WR(reg[eAFBC_DEC_DEF_COLOR], + 0x3FF00000 | /*Y,bit20+*/ + 0x80 << (u + 10) | + 0x80 << v); + /* chroma formatter */ + dim_RDMA_WR(reg[eAFBC_VD_CFMT_CTRL], + (1 << 21) | /* HFORMATTER_YC_RATIO_2_1 */ + (1 << 20) | /* HFORMATTER_EN */ + (vfmt_rpt_first << 16) | /* VFORMATTER_RPTLINE0_EN */ + (vt_ini_phase << 8) | + (16 << 1) | /* VFORMATTER_PHASE_BIT */ + 0); /* different with inp */ + + dim_RDMA_WR(reg[eAFBC_VD_CFMT_W], + (w_aligned << 16) | (w_aligned / 2)); + dim_RDMA_WR(reg[eAFBC_MIF_HOR_SCOPE], + (0 << 16) | ((w_aligned >> 5) - 1)); + dim_RDMA_WR(reg[eAFBC_MIF_VER_SCOPE], + (0 << 16) | ((h_aligned >> 2) - 1)); + + dim_RDMA_WR(reg[eAFBC_PIXEL_HOR_SCOPE], + (0 << 16) | (vf->width - 1)); + dim_RDMA_WR(reg[eAFBC_VD_CFMT_H], out_height); + + dim_RDMA_WR(reg[eAFBC_PIXEL_VER_SCOPE], + 0 << 16 | (vf->height - 1)); + dim_RDMA_WR(reg[eAFBC_SIZE_IN], h_aligned | w_aligned << 16); + dim_RDMA_WR(reg[eAFBC_SIZE_OUT], out_height | w_aligned << 16); + dim_RDMA_WR(reg[eAFBC_HEAD_BADDR], vf->compHeadAddr >> 4); + dim_RDMA_WR(reg[eAFBC_BODY_BADDR], vf->compBodyAddr >> 4); +} + +static void afbcx_power_sw(enum eAFBC_DEC decsel, bool on) /*g12a*/ +{ + unsigned int reg_ctrl; + + if (decsel == eAFBC_DEC0) + reg_ctrl = VD1_AFBCD0_MISC_CTRL; + else + reg_ctrl = VD2_AFBCD1_MISC_CTRL; + if (on) + dim_RDMA_WR_BITS(reg_ctrl, 0, 0, 8); + else + dim_RDMA_WR_BITS(reg_ctrl, 0x55, 0, 8); +} + +static void afbcx_sw(bool on) /*g12a*/ +{ + unsigned int tmp; + unsigned int mask; + unsigned int reg_ctrl, reg_en; + enum eAFBC_DEC dec_sel; + + dec_sel = afbc_get_decnub(); + + if (dec_sel == eAFBC_DEC0) { + reg_ctrl = VD1_AFBCD0_MISC_CTRL; + reg_en = AFBC_ENABLE; + } else { + reg_ctrl = VD2_AFBCD1_MISC_CTRL; + reg_en = VD2_AFBC_ENABLE; + } + + mask = (3 << 20) | (1 << 12) | (1 << 9); + /*clear*/ + tmp = dim_RDMA_RD(reg_ctrl) & (~mask); + + if (on) { + tmp = tmp | + (2 << 20) | + (1 << 12) | + (1 << 9); + dim_RDMA_WR(reg_ctrl, tmp); + dim_RDMA_WR_BITS(VD2_AFBCD1_MISC_CTRL, + (reg_ctrl == VD1_AFBCD0_MISC_CTRL) ? 0 : 1, + 8, 1); + dim_RDMA_WR(reg_en, 0x1600); + dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1); + /*TL1 add mem control bit */ + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + dim_RDMA_WR_BITS(VD1_AFBCD0_MISC_CTRL, 1, 22, 1); + } else { + dim_RDMA_WR(reg_ctrl, tmp); + dim_RDMA_WR(reg_en, 0x1600); + dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1); + if (is_meson_tl1_cpu() || is_meson_tm2_cpu()) + dim_RDMA_WR_BITS(VD1_AFBCD0_MISC_CTRL, 0, 22, 1); + } +#if 0 + PR_INF("%s,on[%d],CTRL[0x%x],en[0x%x]\n", __func__, on, + dim_RDMA_RD(VD1_AFBCD0_MISC_CTRL), + dim_RDMA_RD(VD1_AFBCD0_MISC_CTRL)); +#endif +} + +static void afbc_sw_old(bool on)/*txlx*/ +{ + enum eAFBC_DEC dec_sel; + unsigned int reg_en; + + dec_sel = afbc_get_decnub(); + + if (dec_sel == eAFBC_DEC0) { + /*reg_ctrl = VD1_AFBCD0_MISC_CTRL;*/ + reg_en = AFBC_ENABLE; + } else { + /*reg_ctrl = VD2_AFBCD1_MISC_CTRL;*/ + reg_en = VD2_AFBC_ENABLE; + } + + if (on) { + /* DI inp(current data) switch to AFBC */ + if (dim_RDMA_RD_BITS(VIU_MISC_CTRL0, 29, 1) != 1) + dim_RDMA_WR_BITS(VIU_MISC_CTRL0, 1, 29, 1); + if (dim_RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) != 1) + dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 1, 16, 1); + if (dim_RDMA_RD_BITS(VIU_MISC_CTRL1, 0, 1) != 1) + dim_RDMA_WR_BITS(VIU_MISC_CTRL1, 1, 0, 1); + if (dec_sel == eAFBC_DEC0) { + /*gxl only?*/ + if (dim_RDMA_RD_BITS(VIU_MISC_CTRL0, 19, 1) != 1) + dim_RDMA_WR_BITS(VIU_MISC_CTRL0, 1, 19, 1); + } + if (dim_RDMA_RD(reg_en) != 0x1600) + dim_RDMA_WR(reg_en, 0x1600); + + } else { + dim_RDMA_WR(reg_en, 0); + /* afbc to vpp(replace vd1) enable */ + + if (dim_RDMA_RD_BITS(VIU_MISC_CTRL1, 0, 1) != 0 || + dim_RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) != 0) { + dim_RDMA_WR_BITS(VIU_MISC_CTRL1, 0, 0, 1); + dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 0, 16, 1); + } + } +} + +static bool afbc_is_used(void) +{ + bool ret = false; + + if (dim_RDMA_RD_BITS(VIUB_MISC_CTRL0, 16, 1) == 1) + ret = true; + + /*dim_print("%s:%d\n",__func__,ret);*/ + + return ret; +} + +static void afbc_power_sw(bool on) +{ + /*afbc*/ + enum eAFBC_DEC dec_sel; + unsigned int vpu_sel; + + dec_sel = afbc_get_decnub(); + if (dec_sel == eAFBC_DEC0) + vpu_sel = VPU_AFBC_DEC; + else + vpu_sel = VPU_AFBC_DEC1; + + ext_ops.switch_vpu_mem_pd_vmod(vpu_sel, on); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + afbcx_power_sw(dec_sel, on); +} + +static int afbc_reg_unreg_flag; +void dimh_afbc_reg_sw(bool on) +{ + if (!dimh_afbc_is_supported()) + return; + + if (on && (!afbc_reg_unreg_flag)) { + afbc_power_sw(true); + afbc_reg_unreg_flag = 1; + } + if ((!on) && afbc_reg_unreg_flag) { + afbc_sw_trig(false); + afbc_power_sw(false); + afbc_reg_unreg_flag = 0; + } +} + +static void afbc_sw(bool on) +{ + if (is_meson_gxl_cpu() || is_meson_txlx_cpu()) + afbc_sw_old(on); + else + afbcx_sw(on); +} + +static void afbc_sw_trig(bool on) +{ + afbc_sw(on); +} + +static void afbc_input_sw(bool on) +{ + const unsigned int *reg = afbc_get_regbase(); + unsigned int reg_AFBC_ENABLE; + + if (!dimh_afbc_is_supported()) + return; + + reg_AFBC_ENABLE = reg[eAFBC_ENABLE]; + + /*dim_print("%s:0x%x\n", __func__,reg_AFBC_ENABLE);*/ + if (on) + dim_RDMA_WR_BITS(reg_AFBC_ENABLE, 1, 8, 1); + else + dim_RDMA_WR_BITS(reg_AFBC_ENABLE, 0, 8, 1); +} + +void dimh_enable_mc_di_pre_g12(struct DI_MC_MIF_s *mcinford_mif, + struct DI_MC_MIF_s *mcinfowr_mif, + struct DI_MC_MIF_s *mcvecwr_mif, + unsigned char mcdi_en) +{ + dim_RDMA_WR_BITS(MCDI_MOTINEN, (mcdi_en ? 3 : 0), 0, 2); + if (is_meson_g12a_cpu() || + is_meson_g12b_cpu() || + is_meson_sm1_cpu()) + dim_RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? 0x1bfef7ff : 0)); + else + dim_RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? 0x1bfff7ff : 0)); + + dim_RDMA_WR_BITS(DI_PRE_CTRL, (mcdi_en ? 3 : 0), 16, 2); + + dim_RDMA_WR_BITS(MCINFRD_SCOPE_X, mcinford_mif->size_x, 16, 13); + dim_RDMA_WR_BITS(MCINFRD_SCOPE_Y, mcinford_mif->size_y, 16, 13); + dim_RDMA_WR_BITS(MCINFRD_CTRL1, mcinford_mif->canvas_num, 16, 8); + dim_RDMA_WR_BITS(MCINFRD_CTRL1, 2, 0, 3); + + dim_RDMA_WR_BITS(MCVECWR_X, mcvecwr_mif->size_x, 0, 13); + dim_RDMA_WR_BITS(MCVECWR_Y, mcvecwr_mif->size_y, 0, 13); + dim_RDMA_WR_BITS(MCVECWR_CTRL, mcvecwr_mif->canvas_num, 0, 8); + dim_RDMA_WR_BITS(MCVECWR_CAN_SIZE, mcvecwr_mif->size_y, 0, 13); + dim_RDMA_WR_BITS(MCVECWR_CAN_SIZE, mcvecwr_mif->size_x, 16, 13); + + dim_RDMA_WR_BITS(MCINFWR_X, mcinfowr_mif->size_x, 0, 13); + dim_RDMA_WR_BITS(MCINFWR_Y, mcinfowr_mif->size_y, 0, 13); + dim_RDMA_WR_BITS(MCINFWR_CTRL, mcinfowr_mif->canvas_num, 0, 8); + dim_RDMA_WR_BITS(MCINFWR_CAN_SIZE, mcinfowr_mif->size_y, 0, 13); + dim_RDMA_WR_BITS(MCINFWR_CAN_SIZE, mcinfowr_mif->size_x, 16, 13); +} + +void dimh_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, + unsigned char mcdi_en) +{ + bool me_auto_en = true; + unsigned int ctrl_mode = 0; + + dim_RDMA_WR_BITS(DI_MTN_CTRL1, (mcdi_en ? 3 : 0), 12, 2); + if (is_meson_gxlx_cpu() || is_meson_txhd_cpu()) + me_auto_en = false; + + ctrl_mode = (me_auto_en ? 0x1bfff7ff : 0x1bfe37ff); + dim_RDMA_WR(MCDI_CTRL_MODE, (mcdi_en ? ctrl_mode : 0)); + dim_RDMA_WR_BITS(MCDI_MOTINEN, (mcdi_en ? 3 : 0), 0, 2); + + dim_RDMA_WR(MCDI_MCVECWR_X, di_mcvecwr_mif->size_x); + dim_RDMA_WR(MCDI_MCVECWR_Y, di_mcvecwr_mif->size_y); + dim_RDMA_WR(MCDI_MCINFOWR_X, di_mcinfowr_mif->size_x); + dim_RDMA_WR(MCDI_MCINFOWR_Y, di_mcinfowr_mif->size_y); + + dim_RDMA_WR(MCDI_MCINFORD_X, di_mcinford_mif->size_x); + dim_RDMA_WR(MCDI_MCINFORD_Y, di_mcinford_mif->size_y); + dim_RDMA_WR(MCDI_MCVECWR_CANVAS_SIZE, + (di_mcvecwr_mif->size_x << 16) + di_mcvecwr_mif->size_y); + dim_RDMA_WR(MCDI_MCINFOWR_CANVAS_SIZE, + (di_mcinfowr_mif->size_x << 16) + di_mcinfowr_mif->size_y); + dim_RDMA_WR(MCDI_MCINFORD_CANVAS_SIZE, + (di_mcinford_mif->size_x << 16) + di_mcinford_mif->size_y); + + dim_RDMA_WR(MCDI_MCVECWR_CTRL, + di_mcvecwr_mif->canvas_num | + (0 << 14) | /* sync latch en */ + (dimp_get(eDI_MP_pre_urgent) << 8) | /* urgent */ + (1 << 12) | /*enable reset by frame rst*/ + (0x4031 << 16)); + dim_RDMA_WR(MCDI_MCINFOWR_CTRL, + di_mcinfowr_mif->canvas_num | + (0 << 14) | /* sync latch en */ + (dimp_get(eDI_MP_pre_urgent) << 8) | /* urgent */ + (1 << 12) | /*enable reset by frame rst*/ + (0x4042 << 16)); + dim_RDMA_WR(MCDI_MCINFORD_CTRL, + di_mcinford_mif->canvas_num | + (0 << 10) | /* sync latch en */ + (dimp_get(eDI_MP_pre_urgent) << 8) | /* urgent */ + (1 << 9) | /*enable reset by frame rst*/ + (0x42 << 16)); +} + +void dimh_enable_mc_di_post_g12(struct DI_MC_MIF_s *mcvecrd_mif, + int urgent, bool reverse, int invert_mv) +{ + unsigned int end_x; + + dim_VSYNC_WR_MPEG_REG(MCVECRD_CTRL1, + mcvecrd_mif->canvas_num << 16 | + 2 << 8 | + (reverse ? 3 : 0) << 4 | + 2); + end_x = mcvecrd_mif->size_x + mcvecrd_mif->start_x; + dim_VSYNC_WR_MPEG_REG(MCVECRD_SCOPE_X, + mcvecrd_mif->start_x | + end_x << 16); + dim_VSYNC_WR_MPEG_REG(MCVECRD_SCOPE_Y, + (reverse ? 1 : 0) << 30 | + mcvecrd_mif->start_y | + mcvecrd_mif->end_y << 16); + dim_VSYNC_WR_MPEG_REG_BITS(MCVECRD_CTRL2, urgent, 16, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, mcvecrd_mif->vecrd_offset, + 12, 3); + if (mcvecrd_mif->blend_en) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_mcen_mode), 0, 2); + if (!di_cfg_top_get(eDI_CFG_ref_2)) { + /*(!dimp_get(eDI_MP_post_wr_en)) {*/ + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 3, 18, 2); + } else {/*OTT-3210*/ + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 11, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 2, 18, 2); + } + } else { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 11, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 2, 18, 2); + } + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_mcuv_en), 10, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + invert_mv, 17, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_mcdebug_mode), 2, 3); +} + +void dimh_enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif, + int urgent, bool reverse, int invert_mv) +{ + di_mcvecrd_mif->size_y = + (di_mcvecrd_mif->end_y - di_mcvecrd_mif->start_y + 1); + dim_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)); + dim_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_Y, + (reverse ? 1 : 0) << 30 | + di_mcvecrd_mif->start_y << 16 | + di_mcvecrd_mif->end_y); + dim_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_CANVAS_SIZE, + (di_mcvecrd_mif->size_x << 16) | + di_mcvecrd_mif->size_y); + dim_VSYNC_WR_MPEG_REG(MCDI_MCVECRD_CTRL, + di_mcvecrd_mif->canvas_num | + (urgent << 8) | /* urgent */ + (1 << 9) | /* canvas enable */ + (0 << 10) | + (0x31 << 16)); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, di_mcvecrd_mif->vecrd_offset, + 12, 3); + if (di_mcvecrd_mif->blend_en) + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_mcen_mode), 0, 2); + else + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_mcuv_en), 10, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 1, 11, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + invert_mv, 17, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 3, 18, 2); + } + } else + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_mcuv_en), 9, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_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); + + dim_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 */ + ); + + dim_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 = 1;/* default enable according to vlsi */ + dim_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 */ + dim_RDMA_WR_BITS(DI_INP_GEN_REG2, 1, 0, 1); + } else { + dim_RDMA_WR_BITS(DI_INP_GEN_REG2, 0, 0, 1); + } + + dim_RDMA_WR_BITS(DI_INP_GEN_REG3, mif->bit_mode & 0x3, 8, 2); + dim_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 */ + /* ---------------------- */ + dim_RDMA_WR(DI_INP_LUMA_X0, (mif->luma_x_end0 << 16) | + /* cntl_luma_x_end0 */ + (mif->luma_x_start0 << 0)/* cntl_luma_x_start0 */ + ); + dim_RDMA_WR(DI_INP_LUMA_Y0, (mif->luma_y_end0 << 16) | + /* cntl_luma_y_end0 */ + (mif->luma_y_start0 << 0) /* cntl_luma_y_start0 */ + ); + dim_RDMA_WR(DI_INP_CHROMA_X0, (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0)); + dim_RDMA_WR(DI_INP_CHROMA_Y0, (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0)); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + dim_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) + ); + + dim_RDMA_WR(DI_INP_LUMA0_RPT_PAT, luma0_rpt_loop_pat); + dim_RDMA_WR(DI_INP_CHROMA0_RPT_PAT, chroma0_rpt_loop_pat); + + /* Dummy pixel value */ + dim_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); + + dim_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 */ + ); + + dim_RDMA_WR(DI_MEM_FMT_W, + (y_length << 16) | /* hz format width */ + (c_length << 0) /* vt format width */ + ); +} + +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); + + dim_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 */ + ); + + dim_RDMA_WR(DI_CHAN2_FMT_W, (y_length << 16) | /* hz format width */ + (c_length << 0) /* vt format width */ + ); +} + +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 = 1;/* default enable according to vlsi */ + dim_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 */ + dim_RDMA_WR_BITS(DI_MEM_GEN_REG2, 1, 0, 1); + } else { + dim_RDMA_WR_BITS(DI_MEM_GEN_REG2, 0, 0, 1); + } + dim_RDMA_WR_BITS(DI_MEM_GEN_REG3, mif->bit_mode & 0x3, 8, 2); + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + dim_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 */ + /* ---------------------- */ + dim_RDMA_WR(DI_MEM_LUMA_X0, + (mif->luma_x_end0 << 16) | + (mif->luma_x_start0 << 0) /* cntl_luma_x_start0 */ + ); + dim_RDMA_WR(DI_MEM_LUMA_Y0, + (mif->luma_y_end0 << 16) | + (mif->luma_y_start0 << 0) /* cntl_luma_y_start0 */ + ); + dim_RDMA_WR(DI_MEM_CHROMA_X0, + (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0) + ); + dim_RDMA_WR(DI_MEM_CHROMA_Y0, + (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0) + ); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + dim_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) + ); + + dim_RDMA_WR(DI_MEM_LUMA0_RPT_PAT, luma0_rpt_loop_pat); + dim_RDMA_WR(DI_MEM_CHROMA0_RPT_PAT, chroma0_rpt_loop_pat); + + /* Dummy pixel value */ + dim_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); + + dim_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 en*/ + (0 << 16) | /* repeat l0 en*/ + (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 */ + ); + + dim_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); + + dim_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 */ + ); + + dim_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); + + dim_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 */ + ); + + dim_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, int vskip_cnt) +{ + 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[(vskip_cnt << 1) + 1]; + /*top*/ + if (mif->src_field_mode == 0) { + chro_rpt_lastl_ctrl = 1; + loop = 0x11; + pat <<= 4; + } + } else { + loop = 0; + pat = vpat[vskip_cnt]; + } + #if 0 + bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + #else + if (mif->set_separate_en) { + bytes_per_pixel = 0; + } else { + if (mif->video_mode) + bytes_per_pixel = 2; + else + bytes_per_pixel = 1; + } + #endif + demux_mode = mif->video_mode; + + /* ---------------------- */ + /* General register */ + /* ---------------------- */ + + dim_VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG, + (1 << 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 + * dim_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG3, mif->bit_mode, 8, 2); + */ + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + dim_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 */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(DI_IF2_LUMA_X0, (mif->luma_x_end0 << 16) | + (mif->luma_x_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF2_LUMA_Y0, (mif->luma_y_end0 << 16) | + (mif->luma_y_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA_X0, (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA_Y0, (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0)); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(DI_IF2_RPT_LOOP, + (loop << 24) | + (loop << 16) | + (loop << 8) | + (loop << 0) + ); + + dim_VSYNC_WR_MPEG_REG(DI_IF2_LUMA0_RPT_PAT, pat); + dim_VSYNC_WR_MPEG_REG(DI_IF2_CHROMA0_RPT_PAT, pat); + + /* Dummy pixel value */ + dim_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, int vskip_cnt) +{ + 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[(vskip_cnt << 1) + 1]; + /*top*/ + if (mif->src_field_mode == 0) { + chro_rpt_lastl_ctrl = 1; + loop = 0x11; + pat <<= 4; + } + } else { + loop = 0; + pat = vpat[vskip_cnt]; + } + #if 0 + bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + #else + if (mif->set_separate_en) { + bytes_per_pixel = 0; + } else { + if (mif->video_mode) + bytes_per_pixel = 2; + else + bytes_per_pixel = 1; + } + #endif + demux_mode = mif->video_mode; + + /* ---------------------- */ + /* General register */ + /* ---------------------- */ + + dim_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, + (1 << 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 */ + ); + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + dim_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 */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(DI_IF1_LUMA_X0, + (mif->luma_x_end0 << 16) | + (mif->luma_x_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF1_LUMA_Y0, + (mif->luma_y_end0 << 16) | + (mif->luma_y_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA_X0, + (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA_Y0, + (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0)); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(DI_IF1_RPT_LOOP, + (loop << 24) | + (loop << 16) | + (loop << 8) | + (loop << 0) + ); + + dim_VSYNC_WR_MPEG_REG(DI_IF1_LUMA0_RPT_PAT, pat); + dim_VSYNC_WR_MPEG_REG(DI_IF1_CHROMA0_RPT_PAT, pat); + + /* Dummy pixel value */ + dim_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 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; + } + #if 0 + bytes_per_pixel = mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + #else + if (mif->set_separate_en) { + bytes_per_pixel = 0; + } else { + if (mif->video_mode) + bytes_per_pixel = 2; + else + bytes_per_pixel = 1; + } + #endif + demux_mode = mif->video_mode; + + /* ---------------------- */ + /* General register */ + /* ---------------------- */ + reset_on_gofield = 1;/* default enable according to vlsi */ + dim_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*/ + (chro_rpt_lastl_ctrl << 6) | + ((mif->set_separate_en != 0) << 1) | + (0 << 0) /* cntl_enable */ + ); + /* ---------------------- */ + /* Canvas */ + /* ---------------------- */ + if (mif->set_separate_en == 2) { + /* Enable NV12 Display */ + dim_RDMA_WR_BITS(DI_CHAN2_GEN_REG2, 1, 0, 1); + } else { + dim_RDMA_WR_BITS(DI_CHAN2_GEN_REG2, 0, 0, 1); + } + dim_RDMA_WR_BITS(DI_CHAN2_GEN_REG3, mif->bit_mode & 0x3, 8, 2); + dim_RDMA_WR(DI_CHAN2_CANVAS0, (mif->canvas0_addr2 << 16) | + (mif->canvas0_addr1 << 8) | + (mif->canvas0_addr0 << 0)); + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + dim_RDMA_WR(DI_CHAN2_LUMA_X0, (mif->luma_x_end0 << 16) | + /* cntl_luma_x_end0 */ + (mif->luma_x_start0 << 0)); + dim_RDMA_WR(DI_CHAN2_LUMA_Y0, (mif->luma_y_end0 << 16) | + (mif->luma_y_start0 << 0)); + dim_RDMA_WR(DI_CHAN2_CHROMA_X0, (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0)); + dim_RDMA_WR(DI_CHAN2_CHROMA_Y0, (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0)); + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + dim_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) + ); + + dim_RDMA_WR(DI_CHAN2_LUMA0_RPT_PAT, luma0_rpt_loop_pat); + + /* Dummy pixel value */ + dim_RDMA_WR(DI_CHAN2_DUMMY_PIXEL, 0x00808000); + + 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. */ + } +} + +static void set_di_if0_mif(struct DI_MIF_s *mif, int urgent, int hold_line, + int vskip_cnt, int post_write_en) +{ + unsigned int pat, loop = 0; + unsigned int bytes_per_pixel, demux_mode; + + if (mif->set_separate_en == 1) { + pat = vpat[(vskip_cnt << 1) + 1]; + if (mif->src_field_mode == 0) {/* top */ + loop = 0x11; + pat <<= 4; + } + } else { + loop = 0; + pat = vpat[vskip_cnt]; + + if (post_write_en) { + bytes_per_pixel = + mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + demux_mode = mif->video_mode; + dim_VSYNC_WR_MPEG_REG(VD1_IF0_GEN_REG, + (1 << 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 */ + /* ---------------------- */ + dim_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 */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_X0, (mif->luma_x_end0 << 16) | + (mif->luma_x_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA_Y0, (mif->luma_y_end0 << 16) | + (mif->luma_y_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_X0, (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA_Y0, (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0)); + } + + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(VD1_IF0_RPT_LOOP, + (loop << 24) | + (loop << 16) | + (loop << 8) | + (loop << 0)); + dim_VSYNC_WR_MPEG_REG(VD1_IF0_LUMA0_RPT_PAT, pat); + dim_VSYNC_WR_MPEG_REG(VD1_IF0_CHROMA0_RPT_PAT, pat); + + if (post_write_en) { + /* 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 */ + /* y_length */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + /* c length */ + mif->chroma_x_end0 - mif->chroma_x_start0 + 1, + 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 */ + /* y_length */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + /* c length */ + ((mif->luma_x_end0 >> 1) - ( + mif->luma_x_start0 >> 1) + 1), + 0); /* hz repeat */ + } + } +} + +static void set_di_if0_fmt_more_g12(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); + + dim_VSYNC_WR_MPEG_REG(DI_IF0_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 */ + ); + + dim_VSYNC_WR_MPEG_REG(DI_IF0_FMT_W, + (y_length << 16) | /* hz format width */ + (c_length << 0) /* vt format width */ + ); +} + +static void set_di_if0_mif_g12(struct DI_MIF_s *mif, int urgent, int hold_line, + int vskip_cnt, int post_write_en) +{ + unsigned int pat, loop = 0; + unsigned int bytes_per_pixel, demux_mode; + + if (mif->set_separate_en == 1) { + pat = vpat[(vskip_cnt << 1) + 1]; + if (mif->src_field_mode == 0) {/* top */ + loop = 0x11; + pat <<= 4; + } + } else { + loop = 0; + pat = vpat[vskip_cnt]; + + bytes_per_pixel = + mif->set_separate_en ? 0 : (mif->video_mode ? 2 : 1); + demux_mode = mif->video_mode; + dim_VSYNC_WR_MPEG_REG(DI_IF0_GEN_REG, + (1 << 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 */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(DI_IF0_CANVAS0, + (mif->canvas0_addr2 << 16) | + (mif->canvas0_addr1 << 8) | + (mif->canvas0_addr0 << 0)); + if (mif->set_separate_en == 2) { + /* Enable NV12 Display */ + dim_RDMA_WR_BITS(DI_IF0_GEN_REG2, 1, 0, 1); + } else { + dim_RDMA_WR_BITS(DI_IF0_GEN_REG2, 0, 0, 1); + } + + /* ---------------------- */ + /* Picture 0 X/Y start,end */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(DI_IF0_LUMA_X0, + (mif->luma_x_end0 << 16) | + (mif->luma_x_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF0_LUMA_Y0, + (mif->luma_y_end0 << 16) | + (mif->luma_y_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA_X0, + (mif->chroma_x_end0 << 16) | + (mif->chroma_x_start0 << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA_Y0, + (mif->chroma_y_end0 << 16) | + (mif->chroma_y_start0 << 0)); + } + /* ---------------------- */ + /* Repeat or skip */ + /* ---------------------- */ + dim_VSYNC_WR_MPEG_REG(DI_IF0_REPEAT_LOOP, + (loop << 24) | + (loop << 16) | + (loop << 8) | + (loop << 0)); + dim_VSYNC_WR_MPEG_REG(DI_IF0_LUMA0_RPT_PAT, pat); + dim_VSYNC_WR_MPEG_REG(DI_IF0_CHROMA0_RPT_PAT, pat); + + /* 4:2:0 block mode. */ + if (mif->set_separate_en != 0) { + set_di_if0_fmt_more_g12( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 1, /* vfmt_en */ + 1, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + /* y_length */ + mif->luma_x_end0 - mif->luma_x_start0 + 1, + /* c length */ + mif->chroma_x_end0 - mif->chroma_x_start0 + 1, + 0); /* hz repeat. */ + } else { + set_di_if0_fmt_more_g12( + 1, /* hfmt_en */ + 1, /* hz_yc_ratio */ + 0, /* hz_ini_phase */ + 0, /* vfmt_en */ + 0, /* vt_yc_ratio */ + 0, /* vt_ini_phase */ + /* y_length */ + mif->luma_x_end0 - + mif->luma_x_start0 + 1, + /* c length */ + ((mif->luma_x_end0 >> 1) - + (mif->luma_x_start0 >> 1) + 1), + 0); /* hz repeat */ + } +} + +static unsigned int di_mc_update; +void dimh_patch_post_update_mc(void) +{ + if (di_mc_update == DI_MC_SW_ON_MASK) + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, 1, 9, 1); +} + +void dimh_patch_post_update_mc_sw(unsigned int cmd, bool on) +{ + unsigned int l_flg = di_mc_update; + + switch (cmd) { + case DI_MC_SW_IC: + if (is_meson_gxtvbb_cpu() || + is_meson_txl_cpu() || + is_meson_txlx_cpu() || + is_meson_txhd_cpu()) { + di_mc_update |= DI_MC_SW_IC; + } + break; + case DI_MC_SW_REG: + if (on) { + di_mc_update |= cmd; + di_mc_update &= ~DI_MC_SW_OTHER; + } else { + di_mc_update &= ~(cmd | DI_MC_SW_OTHER); + } + break; + case DI_MC_SW_OTHER: + +/* case DI_MC_SW_POST:*/ + if (on) + di_mc_update |= cmd; + else + di_mc_update &= ~cmd; + + break; + } + + if (l_flg != di_mc_update) + pr_debug("%s:0x%x->0x%x\n", __func__, l_flg, di_mc_update); +} + +void dimh_post_ctrl(enum DI_HW_POST_CTRL contr, unsigned int post_write_en) +{ + unsigned int reg_val; + + if (!post_write_en || !cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + return; + + switch (contr) { + case DI_HW_POST_CTRL_INIT: + dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, + 0x80000000 | + dimp_get(eDI_MP_line_num_post_frst)); + break; + case DI_HW_POST_CTRL_RESET: /*replace post_frame_reset_g12a*/ + reg_val = (0xc3200000 | dimp_get(eDI_MP_line_num_post_frst)); + dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val); + reg_val = (0x83200000 | dimp_get(eDI_MP_line_num_post_frst)); + dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val); + + break; + } +} + +void dimh_initial_di_post_2(int hsize_post, int vsize_post, + int hold_line, bool post_write_en) +{ + di_post_set_flow(post_write_en, eDI_POST_FLOW_STEP1_STOP);/*dbg a*/ + dim_VSYNC_WR_MPEG_REG(DI_POST_SIZE, + (hsize_post - 1) | ((vsize_post - 1) << 16)); + + /* if post size < MIN_POST_WIDTH, force old ei */ + if (hsize_post < MIN_POST_WIDTH) + dim_VSYNC_WR_MPEG_REG_BITS(DI_EI_CTRL3, 0, 31, 1); + else + dim_VSYNC_WR_MPEG_REG_BITS(DI_EI_CTRL3, 1, 31, 1); + + /* DI_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_Y, (vsize_post >> 2) - 1); */ + dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_Y, (vsize_post - 1)); + dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_Y, + ((vsize_post >> 2) << 16) | + (2 * (vsize_post >> 2) - 1)); + dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_Y, + ((2 * (vsize_post >> 2)) << 16) | + (3 * (vsize_post >> 2) - 1)); + dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_Y, + ((3 * (vsize_post >> 2)) << 16) | + (vsize_post - 1)); + dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG0_X, (hsize_post - 1)); + dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG1_X, (hsize_post - 1)); + dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG2_X, (hsize_post - 1)); + dim_VSYNC_WR_MPEG_REG(DI_BLEND_REG3_X, (hsize_post - 1)); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (post_write_en) { + #if 0 + dim_print("%s:VD1_AFBCD0_MISC_CTRL\n", __func__); + #endif + /*di if0 mif to di post*/ + dim_VSYNC_WR_MPEG_REG_BITS(VIUB_MISC_CTRL0, 0, 4, 1); + /*di_mif0_en:select mif to di*/ + #if 0 + DI_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, + 1, 8, 1); + #endif + dim_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, + 0, 8, 1); + } else { + dim_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, + 1, 8, 1); + dim_VSYNC_WR_MPEG_REG_BITS(VIUB_MISC_CTRL0, 0, 4, 1); + } + + } else { + /* enable ma,disable if0 to vpp */ + if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0x50000) { + dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3); + if (post_write_en) + dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, + 1, 28, 1); + } + } + dim_VSYNC_WR_MPEG_REG(DI_POST_CTRL, + (0 << 0) | + (0 << 1) | + (0 << 2) | + (0 << 3) | + (0 << 4) | + (0 << 5) | + (0 << 6) | + ((post_write_en ? 1 : 0) << 7) | + ((post_write_en ? 0 : 1) << 8) | + (0 << 9) | + (0 << 10) | + (0 << 11) | + (0 << 12) | + (hold_line << 16) | + (0 << 29) | + (0x3 << 30) + ); +} + +static void post_bit_mode_config(unsigned char if0, + unsigned char if1, + unsigned char if2, + unsigned char post_wr) +{ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) + return; + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dim_DI_Wr_reg_bits(DI_IF0_GEN_REG3, if0 & 0x3, 8, 2); + else + dim_DI_Wr_reg_bits(VD1_IF0_GEN_REG3, if0 & 0x3, 8, 2); + dim_DI_Wr_reg_bits(DI_IF1_GEN_REG3, if1 & 0x3, 8, 2); + dim_DI_Wr_reg_bits(DI_IF2_GEN_REG3, if2 & 0x3, 8, 2); + dim_DI_Wr_reg_bits(DI_DIWR_Y, post_wr & 0x1, 14, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL) && ((post_wr & 0x3) == 0x3)) + dim_DI_Wr_reg_bits(DI_DIWR_CTRL, 0x3, 22, 2); +} + +void dimh_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 invert_mv, bool pd_enable, bool mc_enable, + int vskip_cnt +) +{ + 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 (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + dim_VSYNC_WR_MPEG_REG(DI_IF0_CANVAS0, + (di_buf0_mif->canvas0_addr2 << 16) | + (di_buf0_mif->canvas0_addr1 << 8) | + (di_buf0_mif->canvas0_addr0 << 0)); + if (!di_ddr_en) { + dim_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG, + 0, 0, 1); + } + if (mc_enable) { + dim_VSYNC_WR_MPEG_REG_BITS(MCVECRD_CTRL1, + di_mcvecrd_mif->canvas_num, + 16, 8); + } + /*motion for current display field.*/ + if (blend_mtn_en) { + dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, + di_mtnprd_mif->canvas_num, + 16, 8); + /* current field mtn canvas index.*/ + } + } else { + if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0x50000) + dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 5, 16, 3); + if (di_ddr_en) + dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 1, 28, 1); + if (ei_en || di_vpp_en || di_ddr_en) + set_di_if0_mif(di_buf0_mif, urgent, + hold_line, vskip_cnt, di_ddr_en); + if (mc_enable) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, + /* canvas enable */ + (1 << 9) | + (urgent << 8) | + di_mcvecrd_mif->canvas_num, + 0, 10); + } + /*motion for current display field.*/ + if (blend_mtn_en) { + dim_VSYNC_WR_MPEG_REG(DI_MTNRD_CTRL, + (di_mtnprd_mif->canvas_num << 8) | + (urgent << 16)); + /*current field mtn canvas index.*/ + } + } + + if (!ei_only && (di_ddr_en || di_vpp_en)) { + dim_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 (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + dim_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 (di_ddr_en) { + dim_VSYNC_WR_MPEG_REG(DI_DIWR_CTRL, + di_diwr_mif->canvas_num | + (urgent << 16) | + (2 << 26) | + (di_ddr_en << 30)); + post_bit_mode_config(di_buf0_mif->bit_mode, + di_buf1_mif->bit_mode, + di_buf2_mif->bit_mode, + di_diwr_mif->bit_mode); + } + + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_en, 31, 1); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, blend_mode, 20, 2); + if ((dimp_get(eDI_MP_pldn_ctrl_rflsh) == 1) && pd_enable) + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3); + + if (mc_enable) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + invert_mv, + 17, 1);/* invert mv */ + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + di_mcvecrd_mif->vecrd_offset, 12, 3); + if (di_mcvecrd_mif->blend_en) { + if (blend_mode == 1) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_mcen_mode), 0, 2); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 0, 11, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 2, 18, 2); + } else { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_mcen_mode), 0, 2); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 1, 11, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + 3, 18, 2); + } + } else { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 0, 2); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 0, 11, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, 2, 18, 2); + } + } + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + dim_VSYNC_WR_MPEG_REG_BITS(DI_POST_GL_THD, + hold_line, 16, 5); + hold_line = 0; + } + + if (!is_meson_txlx_cpu()) + invert_mv = 0; + if (dimp_get(eDI_MP_post_ctrl) != 0) + dim_VSYNC_WR_MPEG_REG(DI_POST_CTRL, + dimp_get(eDI_MP_post_ctrl) | + (0x3 << 30)); + else { + dim_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 wr 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 */ + (invert_mv << 14) | + (hold_line << 16) | /* post hold line number */ + (post_field_num << 29) | /* post field number. */ + (0x3 << 30) /* post soft rst post frame rst. */ + ); + } + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A) && di_ddr_en) { +#if 0 + post_frame_reset_g12a(); +#endif + } else if (di_ddr_en && mc_enable) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_CTRL, 1, 9, 1); + } +} + +static void set_post_mtnrd_mif(struct DI_SIM_MIF_s *mtnprd_mif, + unsigned char urgent) +{ + dim_VSYNC_WR_MPEG_REG(DI_MTNPRD_X, + (mtnprd_mif->start_x << 16) | + (mtnprd_mif->end_x)); + dim_VSYNC_WR_MPEG_REG(DI_MTNPRD_Y, + (mtnprd_mif->start_y << 16) | + (mtnprd_mif->end_y)); + dim_VSYNC_WR_MPEG_REG(DI_MTNRD_CTRL, + (mtnprd_mif->canvas_num << 8) | + (urgent << 16) + ); +} + +static void set_post_mtnrd_mif_g12(struct DI_SIM_MIF_s *mtnprd_mif) +{ + dim_VSYNC_WR_MPEG_REG(MTNRD_SCOPE_X, + (mtnprd_mif->end_x << 16) | + (mtnprd_mif->start_x)); + dim_VSYNC_WR_MPEG_REG(MTNRD_SCOPE_Y, + (mtnprd_mif->end_y << 16) | + (mtnprd_mif->start_y)); + dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, + mtnprd_mif->canvas_num, 16, 8); + dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, 0, 0, 3); +} + +void dimh_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 invert_mv, + int vskip_cnt +) +{ + 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) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + set_di_if0_mif_g12(di_buf0_mif, di_vpp_en, + hold_line, vskip_cnt, di_ddr_en); + /* if di post vpp link disable vd1 for new if0 */ + if (!di_ddr_en) { + dim_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG, + 0, 0, 1); + } + } else + set_di_if0_mif(di_buf0_mif, di_vpp_en, + hold_line, vskip_cnt, di_ddr_en); + } + + set_di_if1_mif(di_buf1_mif, di_vpp_en, hold_line, vskip_cnt); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + set_di_if2_mif(di_buf2_mif, + di_vpp_en, hold_line, vskip_cnt); + /* motion for current display field. */ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + set_post_mtnrd_mif_g12(di_mtnprd_mif); + else + set_post_mtnrd_mif(di_mtnprd_mif, urgent); + if (di_ddr_en) { + dim_VSYNC_WR_MPEG_REG(DI_DIWR_X, + (di_diwr_mif->start_x << 16) | + (di_diwr_mif->end_x)); + dim_VSYNC_WR_MPEG_REG(DI_DIWR_Y, + (3 << 30) | + (di_diwr_mif->start_y << 16) | + /* wr ext en from gxtvbb */ + (1 << 15) | + (di_diwr_mif->end_y)); + dim_VSYNC_WR_MPEG_REG(DI_DIWR_CTRL, + di_diwr_mif->canvas_num | + (urgent << 16) | + (2 << 26) | + (di_ddr_en << 30)); + post_bit_mode_config(di_buf0_mif->bit_mode, + di_buf1_mif->bit_mode, + di_buf2_mif->bit_mode, + di_diwr_mif->bit_mode); + } + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, 7, 22, 3); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + blend_en & 0x1, 31, 1); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + blend_mode & 0x3, 20, 2); + if (!is_meson_txlx_cpu()) + invert_mv = 0; + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + dim_VSYNC_WR_MPEG_REG_BITS(DI_POST_GL_THD, + hold_line, 16, 5); + hold_line = 0; + } + dim_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 write to SDRAM enable. */ + (di_ddr_en << 7) | + (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 */ + (invert_mv << 14) | /* invert mv */ + (hold_line << 16) | /* post hold line number */ + (post_field_num << 29) | /* post field number. */ + (0x3 << 30) /* post soft rst post frame rst. */ + ); +} + +void dimh_pst_trig_resize(void) +{ + dim_VSYNC_WR_MPEG_REG(DI_POST_SIZE, (32 - 1) | ((128 - 1) << 16)); +} + +void dimh_disable_post_deinterlace_2(void) +{ + dim_VSYNC_WR_MPEG_REG(DI_POST_CTRL, 0x3 << 30); + dim_VSYNC_WR_MPEG_REG(DI_POST_SIZE, (32 - 1) | ((128 - 1) << 16)); + dim_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, 0x3 << 30); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + dim_VSYNC_WR_MPEG_REG(DI_IF2_GEN_REG, 0x3 << 30); + /* disable ma,enable if0 to vpp,enable afbc to vpp */ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if ((VSYNC_RD_MPEG_REG(VIU_MISC_CTRL0) & 0x50000) != 0) + dim_VSYNC_WR_MPEG_REG_BITS(VIU_MISC_CTRL0, 0, 16, 4); + /* DI inp(current data) switch to memory */ + dim_VSYNC_WR_MPEG_REG_BITS(VIUB_MISC_CTRL0, 0, 16, 1); + } + /* dim_VSYNC_WR_MPEG_REG(DI_IF1_GEN_REG, + * Rd(DI_IF1_GEN_REG) & 0xfffffffe); + */ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + /*dbg a dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, 0);*/ + di_post_set_flow(1, eDI_POST_FLOW_STEP1_STOP); + dim_print("%s:VD1_AFBCD0_MISC_CTRL 0", __func__); + dim_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 8, 2); + dim_VSYNC_WR_MPEG_REG_BITS(VD1_AFBCD0_MISC_CTRL, 0, 20, 2); + } +} + +void dimh_enable_di_post_mif(enum gate_mode_e mode) +{ + unsigned char gate = 0; + + switch (mode) { + case GATE_OFF: + gate = 1; + break; + case GATE_ON: + gate = 2; + break; + case GATE_AUTO: + gate = 2; + break; + default: + gate = 0; + } + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + /* enable if0 external gate freerun hw issue */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 2, 2); + /* enable if1 external gate freerun hw issue */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 4, 2); + /* enable if1 external gate freerun hw issue */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 6, 2); + /* enable di wr external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 8, 2); + /* enable mtn rd external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 10, 2); + /* enable mv rd external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 12, 2); + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) { + /* enable if1 external gate freerun hw issue */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, + ((gate == 0) ? 2 : gate), 2, 2); + /* enable if2 external gate freerun hw issue */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, + ((gate == 0) ? 2 : gate), 4, 2); + /* enable di wr external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 6, 2); + /* enable mtn rd external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 8, 2); + /* enable mv rd external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, gate, 10, 2); + } +} + +void dim_hw_disable(bool mc_enable) +{ + dimh_enable_di_pre_mif(false, mc_enable); + dim_DI_Wr(DI_POST_SIZE, (32 - 1) | ((128 - 1) << 16)); + dim_DI_Wr_reg_bits(DI_IF1_GEN_REG, 0, 0, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + dim_DI_Wr_reg_bits(DI_IF2_GEN_REG, 0, 0, 1); + /* disable ma,enable if0 to vpp,enable afbc to vpp */ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (Rd_reg_bits(VIU_MISC_CTRL0, 16, 4) != 0) + dim_DI_Wr_reg_bits(VIU_MISC_CTRL0, 0, 16, 4); + /* DI inp(current data) switch to memory */ + dim_DI_Wr_reg_bits(VIUB_MISC_CTRL0, 0, 16, 1); + } + dim_DI_Wr(DI_POST_CTRL, 0); +} + +/* + * old pulldown windows share below ctrl + * registers + * with new pulldown windows + */ +void dim_film_mode_win_config(unsigned int width, unsigned int height) +{ + 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 = 0; + win1_start_x = 0; + win2_start_x = 0; + win3_start_x = 0; + win4_start_x = 0; + win0_end_x = width - 1; + win1_end_x = width - 1; + win2_end_x = width - 1; + win3_end_x = width - 1; + 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 */ + + dim_RDMA_WR(DI_MC_REG0_X, (win0_start_x << 16) | win0_end_x); + dim_RDMA_WR(DI_MC_REG0_Y, (win0_start_y << 16) | win0_end_y); + dim_RDMA_WR(DI_MC_REG1_X, (win1_start_x << 16) | win1_end_x); + dim_RDMA_WR(DI_MC_REG1_Y, (win1_start_y << 16) | win1_end_y); + dim_RDMA_WR(DI_MC_REG2_X, (win2_start_x << 16) | win2_end_x); + dim_RDMA_WR(DI_MC_REG2_Y, (win2_start_y << 16) | win2_end_y); + dim_RDMA_WR(DI_MC_REG3_X, (win3_start_x << 16) | win3_end_x); + dim_RDMA_WR(DI_MC_REG3_Y, (win3_start_y << 16) | win3_end_y); + dim_RDMA_WR(DI_MC_REG4_X, (win4_start_x << 16) | win4_end_x); + dim_RDMA_WR(DI_MC_REG4_Y, (win4_start_y << 16) | win4_end_y); +} + +/* + * old pulldown detction module, global field diff/num & frame + * diff/numm and 5 window included + */ +void dim_read_pulldown_info(unsigned int *glb_frm_mot_num, + unsigned int *glb_fid_mot_num) +{ + /* + * addr will increase by 1 automatically + */ + dim_DI_Wr(DI_INFO_ADDR, 1); + *glb_frm_mot_num = (Rd(DI_INFO_DATA) & 0xffffff); + dim_DI_Wr(DI_INFO_ADDR, 4); + *glb_fid_mot_num = (Rd(DI_INFO_DATA) & 0xffffff); +} + +#if 0 /*move from deinterlace_hw.c to pulldown_drv.c*/ + +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); +} + +#endif +/* + * DIPD_RO_COMB_0~DIPD_RO_COMB11 and DI_INFO_DATA + * will be reset, so call this function after all + * data have be fetched + */ +void dim_pulldown_info_clear_g12a(void) +{ + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) + dim_RDMA_WR_BITS(DI_PRE_CTRL, 1, 30, 1); +} + +/* + * manual reset contrd, cont2rd, mcinford mif + * which fix after g12a + */ +static void reset_pre_simple_rd_mif_g12(unsigned char madi_en, + unsigned char mcdi_en) +{ + unsigned int reg_val = 0; + + if (madi_en || mcdi_en) { + dim_RDMA_WR_BITS(CONTRD_CTRL2, 1, 31, 1); + dim_RDMA_WR_BITS(CONT2RD_CTRL2, 1, 31, 1); + dim_RDMA_WR_BITS(MCINFRD_CTRL2, 1, 31, 1); + reg_val = dim_RDMA_RD(DI_PRE_CTRL); + if (madi_en) + reg_val |= (1 << 25); + if (mcdi_en) + reg_val |= (1 << 10); + /* enable cont rd&mcinfo rd, manual start */ + dim_RDMA_WR(DI_PRE_CTRL, reg_val); + dim_RDMA_WR_BITS(CONTRD_CTRL2, 0, 31, 1); + dim_RDMA_WR_BITS(CONT2RD_CTRL2, 0, 31, 1); + dim_RDMA_WR_BITS(MCINFRD_CTRL2, 0, 31, 1); + } +} + +/* + * frame reset for pre which have nothing with encoder + * go field + */ +void dim_pre_frame_reset_g12(unsigned char madi_en, + unsigned char mcdi_en) +{ + unsigned int reg_val = 0; + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12B)) { + reset_pre_simple_rd_mif_g12(madi_en, mcdi_en); + } else { + reg_val = dim_RDMA_RD(DI_PRE_CTRL); + if (madi_en) + reg_val |= (1 << 25); + if (mcdi_en) + reg_val |= (1 << 10); + dim_RDMA_WR(DI_PRE_CTRL, reg_val); + } + /* reset simple mif which framereset not cover */ + dim_RDMA_WR_BITS(CONTWR_CAN_SIZE, 1, 14, 1); + dim_RDMA_WR_BITS(MTNWR_CAN_SIZE, 1, 14, 1); + dim_RDMA_WR_BITS(MCVECWR_CAN_SIZE, 1, 14, 1); + dim_RDMA_WR_BITS(MCINFWR_CAN_SIZE, 1, 14, 1); + + dim_RDMA_WR_BITS(CONTWR_CAN_SIZE, 0, 14, 1); + dim_RDMA_WR_BITS(MTNWR_CAN_SIZE, 0, 14, 1); + dim_RDMA_WR_BITS(MCVECWR_CAN_SIZE, 0, 14, 1); + dim_RDMA_WR_BITS(MCINFWR_CAN_SIZE, 0, 14, 1); + + reg_val = 0xc3200000 | dimp_get(eDI_MP_line_num_pre_frst); + dim_RDMA_WR(DI_PRE_GL_CTRL, reg_val); + reg_val = 0x83200000 | dimp_get(eDI_MP_line_num_pre_frst); + dim_RDMA_WR(DI_PRE_GL_CTRL, reg_val); +} + +/* + * frame + soft reset for the pre modules + */ +void dim_pre_frame_reset(void) +{ + dim_RDMA_WR_BITS(DI_PRE_CTRL, 3, 30, 2); +} + +/* + * frame reset for post which have nothing with encoder + * go field + */ +void post_frame_reset_g12a(void) +{ + unsigned int reg_val = 0; + + reg_val = (0xc0200000 | dimp_get(eDI_MP_line_num_post_frst)); + dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val); + reg_val = (0x80200000 | dimp_get(eDI_MP_line_num_post_frst)); + dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, reg_val); +} + +void dim_post_read_reverse_irq(bool reverse, unsigned char mc_pre_flag, + bool mc_enable) +{ + unsigned short flag_val = 1; + + mc_pre_flag = dimp_get(eDI_MP_if2_disable) ? 1 : mc_pre_flag; + if (reverse) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + dim_VSYNC_WR_MPEG_REG_BITS(DI_IF0_GEN_REG2, 3, 2, 2); + dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, 3, 4, 2); + } else { + dim_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0xf, 2, 4); + dim_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0xf, 17, 4); + } + dim_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG2, 3, 2, 2); + dim_VSYNC_WR_MPEG_REG_BITS(VD2_IF0_GEN_REG2, 0xf, 2, 4); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + dim_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG2, 3, 2, 2); + if (mc_enable) { + /* motion vector read reverse*/ + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_X, 1, 30, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_Y, 1, 30, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { + if (is_meson_txlx_cpu()) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_pre_flag), 8, 2); + flag_val = + (dimp_get(eDI_MP_pre_flag) != 2) ? + 0 : 1; + } else { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + mc_pre_flag, 8, 2); + flag_val = (mc_pre_flag != 2) ? 0 : 1; + } + dim_VSYNC_WR_MPEG_REG_BITS( + MCDI_MC_CRTL, flag_val, 11, 1); + /* disable if2 for wave if1 case, + *disable mc for pq issue + */ + if (dimp_get(eDI_MP_if2_disable)) { + dim_VSYNC_WR_MPEG_REG_BITS( + MCDI_MC_CRTL, 0, 11, 1); + dim_VSYNC_WR_MPEG_REG_BITS( + DI_IF2_GEN_REG, 0, 0, 1); + if (cpu_after_eq( + MESON_CPU_MAJOR_ID_GXLX)) + dim_VSYNC_WR_MPEG_REG_BITS( + MCDI_MC_CRTL, 0, 18, 1); + } + } else + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + mc_pre_flag, 8, 1); + } + } else { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + dim_VSYNC_WR_MPEG_REG_BITS(DI_IF0_GEN_REG2, 0, 2, 2); + dim_VSYNC_WR_MPEG_REG_BITS(MTNRD_CTRL1, 0, 4, 2); + } else { + dim_VSYNC_WR_MPEG_REG_BITS(VD1_IF0_GEN_REG2, 0, 2, 4); + dim_VSYNC_WR_MPEG_REG_BITS(DI_MTNRD_CTRL, 0, 17, 4); + } + dim_VSYNC_WR_MPEG_REG_BITS(DI_IF1_GEN_REG2, 0, 2, 2); + dim_VSYNC_WR_MPEG_REG_BITS(VD2_IF0_GEN_REG2, 0, 2, 4); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + dim_VSYNC_WR_MPEG_REG_BITS(DI_IF2_GEN_REG2, 0, 2, 2); + if (mc_enable) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_X, 0, 30, 1); + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MCVECRD_Y, 0, 30, 1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { + if (is_meson_txlx_cpu()) { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + dimp_get(eDI_MP_pre_flag), + 8, 2); + flag_val = + (dimp_get(eDI_MP_pre_flag) != 2) ? + 0 : 1; + } else { + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + mc_pre_flag, 8, 2); + flag_val = (mc_pre_flag != 2) ? 0 : 1; + } + dim_VSYNC_WR_MPEG_REG_BITS( + MCDI_MC_CRTL, flag_val, 11, 1); + /* disable if2 for wave if1 case */ + if (dimp_get(eDI_MP_if2_disable)) { + dim_VSYNC_WR_MPEG_REG_BITS( + MCDI_MC_CRTL, 0, 11, 1); + dim_VSYNC_WR_MPEG_REG_BITS( + DI_IF2_GEN_REG, 0, 0, 1); + if (cpu_after_eq( + MESON_CPU_MAJOR_ID_GXLX)) + dim_VSYNC_WR_MPEG_REG_BITS( + MCDI_MC_CRTL, 0, 18, 1); + } + } else + dim_VSYNC_WR_MPEG_REG_BITS(MCDI_MC_CRTL, + mc_pre_flag, 8, 1); + } + } +} + +void dim_set_power_control(unsigned char enable) +{ + ext_ops.switch_vpu_mem_pd_vmod(VPU_VIU_VD1, + enable ? true : false); + ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST, + enable ? true : false); +} + +void dim_top_gate_control(bool top_en, bool mc_en) +{ + if (top_en) { + /* enable clkb input */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 0, 1); + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 15, 1); + /* enable slow clk */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, mc_en ? 1 : 0, 10, 1); + /* enable di arb */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 0, 2); + } else { + /* disable clkb input */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 0, 1); + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 15, 1); + /* disable slow clk */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 10, 1); + /* disable di arb */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 0, 2); + } +} + +void dim_pre_gate_control(bool gate, bool mc_enable) +{ + if (gate) { + /* enable ma pre clk */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 8, 1); + /* enable mc clk */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 11, 1); + /* enable pd clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 2, 2, 2); + /* enable motion clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 2, 4, 2); + /* enable deband clk gate freerun for hw issue */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 2, 6, 2); + /* enable input mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 16, 2); + /* enable mem mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 18, 2); + /* enable chan2 mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 20, 2); + /* enable nr wr mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 22, 2); + /* enable mtn wr mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 2, 24, 2); + if (mc_enable) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 0, 12, 2); + else + /* enable me clk always run vlsi issue */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 3, 12, 2); + /* + * enable mc pre mv(wr) mcinfo w/r + * mif external gate + */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, + 2, 26, 2); + } + /* cowork with auto gate to config reg */ + dim_DI_Wr_reg_bits(DI_PRE_CTRL, 3, 2, 2); + } else { + /* disable ma pre clk */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 8, 1); + /* disable mc clk */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 11, 1); + /* disable pd clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 1, 2, 2); + /* disable motion clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 1, 4, 2); + /* disable deband clk gate freerun for hw issue */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 1, 6, 2); + /* disable input mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 16, 2); + /* disable mem mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 18, 2); + /* disable chan2 mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 20, 2); + /* disable nr wr mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 22, 2); + /* disable mtn wr mif external gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, 1, 24, 2); + if (mc_enable) { + /* disable mc pre mv(wr) mcinfo + * w/r mif external gate + */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL1, + 1, 26, 2); + /* disable me clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL2, 1, 12, 2); + } + } +} + +void dim_post_gate_control(bool gate) +{ + if (gate) { + /* enable clk post div */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 12, 1); + /* enable post line buf/fifo/mux clk */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 1, 9, 1); + /* enable blend1 clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 0, 0, 2); + /* enable ei clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 0, 2, 2); + /* enable ei_0 clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 0, 4, 2); + } else { + /* disable clk post div */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 12, 1); + /* disable post line buf/fifo/mux clk */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL0, 0, 9, 1); + /* disable blend1 clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 1, 0, 2); + /* disable ei clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 1, 2, 2); + /* disable ei_0 clk gate */ + dim_DI_Wr_reg_bits(VIUB_GCLK_CTRL3, 1, 4, 2); + } +} + +static void di_async_reset(void)/*2019-01-17 add for debug*/ +{ + /*wrmif async reset*/ + dim_RDMA_WR_BITS(VIUB_SW_RESET, 1, 14, 1); + dim_RDMA_WR_BITS(VIUB_SW_RESET, 0, 14, 1); +} + +static void di_pre_rst_frame(void) +{ + dim_RDMA_WR(DI_PRE_CTRL, Rd(DI_PRE_CTRL) | (1 << 31)); +} + +static void di_pre_nr_enable(bool on) +{ + if (on) + dim_RDMA_WR_BITS(DI_PRE_CTRL, 1, 0, 1); + else + dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 0, 1); +} + +void dim_pre_nr_wr_done_sel(bool on) +{ + if (on) /*wait till response finish*/ + dim_RDMA_WR_BITS(DI_CANVAS_URGENT0, 1, 8, 1); + else + dim_RDMA_WR_BITS(DI_CANVAS_URGENT0, 0, 0, 1); +} + +void dim_rst_protect(bool on) +{ + if (on) + dim_RDMA_WR_BITS(DI_NRWR_Y, 1, 15, 1); + else + dim_RDMA_WR_BITS(DI_NRWR_Y, 0, 15, 1); +} + +/*bit 10,12,16,18 [3:1]*/ +/*#define PRE_ID_MASK (0x5140e) */ +#define PRE_ID_MASK (0x51400) + +/*bit 8,10,14,16*/ +#define PRE_ID_MASK_TL1 (0x14500) + +static bool di_pre_idle(void) +{ + bool ret = false; + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if ((dim_RDMA_RD(DI_ARB_DBG_STAT_L1C1) & + PRE_ID_MASK_TL1) == PRE_ID_MASK_TL1) + ret = true; + } else { + if ((dim_RDMA_RD(DI_ARB_DBG_STAT_L1C1_OLD) & + PRE_ID_MASK) == PRE_ID_MASK) + ret = true; + } + + return ret; +} + +void dim_arb_sw(bool on) +{ + int i; + u32 REG_VPU_WRARB_REQEN_SLV_L1C1; + u32 REG_VPU_RDARB_REQEN_SLV_L1C1; + u32 REG_VPU_ARB_DBG_STAT_L1C1; + u32 WRARB_onval; + u32 WRARB_offval; + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + REG_VPU_WRARB_REQEN_SLV_L1C1 = DI_WRARB_REQEN_SLV_L1C1; + REG_VPU_RDARB_REQEN_SLV_L1C1 = DI_RDARB_REQEN_SLV_L1C1; + REG_VPU_ARB_DBG_STAT_L1C1 = DI_ARB_DBG_STAT_L1C1; + if (on) + WRARB_onval = 0x3f; + else + WRARB_offval = 0x3e; + } else { + REG_VPU_WRARB_REQEN_SLV_L1C1 = DI_WRARB_REQEN_SLV_L1C1_OLD; + REG_VPU_RDARB_REQEN_SLV_L1C1 = DI_RDARB_REQEN_SLV_L1C1_OLD; + REG_VPU_ARB_DBG_STAT_L1C1 = DI_ARB_DBG_STAT_L1C1_OLD; + if (on) + WRARB_onval = 0x3f; + else + WRARB_offval = 0x2b; + } + + if (on) { + dim_RDMA_WR(REG_VPU_WRARB_REQEN_SLV_L1C1, WRARB_onval); + dim_RDMA_WR(REG_VPU_RDARB_REQEN_SLV_L1C1, 0xffff); + } else { + /*close arb:*/ + dim_RDMA_WR(REG_VPU_WRARB_REQEN_SLV_L1C1, WRARB_offval); + dim_RDMA_WR(REG_VPU_RDARB_REQEN_SLV_L1C1, 0xf1f1); + + di_pre_nr_enable(false); /*by Feijun*/ + /*check status*/ + if (!di_pre_idle()) { + PR_ERR("%s:1:0x[%x]\n", __func__, + dim_RDMA_RD(REG_VPU_ARB_DBG_STAT_L1C1)); + for (i = 0; i < 9; i++) { + if (di_pre_idle()) + break; + } + + if (!di_pre_idle()) { + di_pre_rst_frame(); + + for (i = 0; i < 9; i++) { + if (di_pre_idle()) + break; + } + if (!di_pre_idle()) + PR_ERR("%s:2\n", __func__); + } + } + if (di_pre_idle()) + di_async_reset(); + } +} + +/* keep 0x1700' bit8 bit9 bit11 bit28 : 1*/ + +void dbg_set_DI_PRE_CTRL(void) +{ + unsigned int val; + unsigned int mask, tmp; + + mask = 0x10000b00; + + val = Rd(DI_PRE_CTRL); + tmp = (~mask) & val; + tmp = tmp | 0x10000000; + + dim_DI_Wr(DI_PRE_CTRL, tmp); +} + +/************************************* + *VIUB_SW_RESET's bits: + * [1][2] + * [10][11] + * [12][13][14] + * [16][17] + * [27] + * [28][31] + * all bits set 1 and then set 0 + *************************************/ +void di_async_reset2(void)/*2019-04-05 add for debug*/ +{ + unsigned int mask, val1, val2, val3; + + mask = 0x98037c06; + val1 = Rd(VIUB_SW_RESET); + val2 = val1 | mask; + + dim_DI_Wr(VIUB_SW_RESET, val2); + val3 = val2 & (~mask); + dim_DI_Wr(VIUB_SW_RESET, val3); + pr_info("%s:0x%x,0x%x,0x%x\n", __func__, val1, val2, val3); +} + +#define DI_NOP_REG1 (0x2fcb) +#define DI_NOP_REG2 (0x2fcd) + +void h_dbg_reg_set(unsigned int val) +{ + struct di_hpst_s *pst = get_hw_pst(); + enum eDI_PST_ST pst_st = pst->state; + unsigned int valb; + + dim_DI_Wr(DI_NOP_REG1, val); + + valb = pst_st; + if (pst->curr_ch) + valb = pst_st | 0x80000000; + + dim_DI_Wr(DI_NOP_REG2, valb); +} + +/*below for post */ +void post_mif_sw(bool on) +{ + if (on) { + dim_RDMA_WR_BITS(DI_IF0_GEN_REG, 1, 0, 1); + /*by feijun 2018-11-19*/ + dim_RDMA_WR_BITS(DI_IF1_GEN_REG, 1, 0, 1); + /*by feijun 2018-11-19*/ + dim_RDMA_WR_BITS(DI_IF2_GEN_REG, 1, 0, 1); + + dim_RDMA_WR_BITS(DI_POST_CTRL, 1, 7, 1); + } else { + dim_RDMA_WR_BITS(DI_IF0_GEN_REG, 0, 0, 1); + /*by feijun 2018-11-19*/ + dim_RDMA_WR_BITS(DI_IF1_GEN_REG, 0, 0, 1); + /*by feijun 2018-11-19*/ + dim_RDMA_WR_BITS(DI_IF2_GEN_REG, 0, 0, 1); + dim_RDMA_WR_BITS(DI_POST_CTRL, 0, 7, 1); + } + dim_print("%s:%d\n", __func__, on); +} + +void post_close_new(void) +{ + unsigned int data32; + + post_mif_sw(false); + data32 = Rd(DI_INTR_CTRL); + /*intr_mode*/ + dim_DI_Wr(DI_INTR_CTRL, (data32 & 0xffff0004) | (3 << 30)); + di_post_set_flow(1, eDI_POST_FLOW_STEP1_STOP); /*dbg a*/ +} + +/*asynchronous rest ,2018-11-19 from feijun: after set reset ,*/ +/*mif setting must set again*/ +void di_post_reset(void) +{ +#if 0 + 0x2001 = 0x48300; + 0x2001 = 0x0; + 0x2002 = 0x30c1; + 0x2002 = 0x0; + + 0x2001 = 0x483c0; + 0x2001 = 0x0; + 0x2002 = 0x3001; + 0x2002 = 0x0; +#endif + Wr(VIUB_SW_RESET, 0x483c0); + Wr(VIUB_SW_RESET, 0x0); + + Wr(VIUB_SW_RESET0, 0x3001); + Wr(VIUB_SW_RESET0, 0x0); + pr_info("%s\n", __func__); +} + +void post_dbg_contr(void) +{ + dim_RDMA_WR_BITS(DI_IF0_GEN_REG3, 1, 11, 1); + dim_RDMA_WR_BITS(DI_IF1_GEN_REG3, 1, 11, 1); + dim_RDMA_WR_BITS(DI_IF2_GEN_REG3, 1, 11, 1); +} + +void di_post_set_flow(unsigned int post_wr_en, enum eDI_POST_FLOW step) +{ + unsigned int val; + + if (!post_wr_en) + return; + + switch (step) { + case eDI_POST_FLOW_STEP1_STOP: + /*val = (0xc0200000 | line_num_post_frst);*/ + val = (0xc0000000 | 1); + dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, val); + break; + case eDI_POST_FLOW_STEP2_START: + /*val = (0x80200000 | line_num_post_frst);*/ + val = (0x80200000 | 1); + dim_VSYNC_WR_MPEG_REG(DI_POST_GL_CTRL, val); + break; + } +} + +/*add 2019-04-25 for post crash debug*/ +void hpst_power_ctr(bool on) +{ + if (on) { + ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST, + true); + dim_post_gate_control(true); + dimh_enable_di_post_mif(GATE_AUTO); + } else { + dimh_enable_di_post_mif(GATE_OFF); + dim_post_gate_control(false); + ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST, + false); + } + pr_info("%s:%d\n", __func__, on); +} + +void hpst_dbg_power_ctr_trig(unsigned int cmd) +{ + if (cmd) + hpst_power_ctr(true); + else + hpst_power_ctr(false); +} + +void hpst_dbg_mem_pd_trig(unsigned int cmd) +{ + ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST, + false); + ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST, + true); +/* pr_info("%s\n", __func__);*/ +} + +void hpst_mem_pd_sw(unsigned int on) +{ + if (on) + ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST, + true); + else + ext_ops.switch_vpu_mem_pd_vmod(VPU_DI_POST, + false); +} + +void hpst_vd1_sw(unsigned int on) +{ + if (on) + ext_ops.switch_vpu_mem_pd_vmod(VPU_VIU_VD1, + true); + else + ext_ops.switch_vpu_mem_pd_vmod(VPU_VIU_VD1, + false); +} + +void hpst_dbg_trig_gate(unsigned int cmd) +{ + dim_post_gate_control(false); + dim_post_gate_control(true); + pr_info("%s\n", __func__); +} + +void hpst_dbg_trig_mif(unsigned int cmd) +{ + dimh_enable_di_post_mif(GATE_OFF); + dimh_enable_di_post_mif(GATE_AUTO); + pr_info("%s\n", __func__); +} + +/**/ +/* + * enable/disable mc pre mif mcinfo&mv + */ +static void mc_pre_mif_ctrl_g12(bool enable) +{ + unsigned char mif_ctrl = 0; + + mif_ctrl = enable ? 1 : 0; + /* enable mcinfo rd mif */ + dim_RDMA_WR_BITS(DI_PRE_CTRL, mif_ctrl, 10, 1); + /* enable mv wr mif */ + dim_RDMA_WR_BITS(MCVECWR_CTRL, mif_ctrl, 12, 1); + /* enable mcinfo wr mif */ + dim_RDMA_WR_BITS(MCINFWR_CTRL, mif_ctrl, 12, 1); +} + +static void mc_pre_mif_ctrl(bool enable) +{ + if (enable) { + /* gate clk */ + dim_RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 9, 1); + /* gate clk */ + dim_RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 9, 1); + /* mcinfo rd req en =1 */ + dim_RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 1, 9, 1); + /* mv wr req en =1 */ + dim_RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 12, 1); + /* mcinfo wr req en =1 */ + dim_RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 12, 1); + } else { + /* no gate clk */ + dim_RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 1, 9, 1); + /* no gate clk */ + dim_RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 1, 9, 1); + /* mcvec wr req en =0 */ + dim_RDMA_WR_BITS(MCDI_MCVECWR_CTRL, 0, 12, 1); + /* mcinfo wr req en =0 */ + dim_RDMA_WR_BITS(MCDI_MCINFOWR_CTRL, 0, 12, 1); + /* mcinfo rd req en = 0 */ + dim_RDMA_WR_BITS(MCDI_MCINFORD_CTRL, 0, 9, 1); + } +} + +/* + * enable/disable madi pre mif, mtn&cont + */ +static void ma_pre_mif_ctrl_g12(bool enable) +{ + if (enable) { + /* enable cont wr mif */ + dim_RDMA_WR_BITS(CONTWR_CTRL, 1, 12, 1); + /* enable mtn wr mif */ + dim_RDMA_WR_BITS(MTNWR_CTRL, 1, 12, 1); + /* enable cont rd mif */ + } else { + dim_RDMA_WR_BITS(MTNWR_CTRL, 0, 12, 1); + dim_RDMA_WR_BITS(CONTWR_CTRL, 0, 12, 1); + /* disable cont rd */ + dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 25, 1); + } +} + +/* + * use logic enable/disable replace mif + */ +static void ma_pre_mif_ctrl(bool enable) +{ + if (!enable) { + /* mtn wr req en =0 */ + dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 1, 1); + /* cont wr req en =0 */ + dim_RDMA_WR_BITS(DI_MTN_1_CTRL1, 0, 31, 1); + /* disable cont rd */ + dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 25, 1); + } +} + +/* + * enable/disable inp&chan2&mem&nrwr mif + */ +static void di_pre_data_mif_ctrl(bool enable) +{ + if (enable) { + /* enable input mif*/ + dim_DI_Wr(DI_CHAN2_GEN_REG, Rd(DI_CHAN2_GEN_REG) | 0x1); + dim_DI_Wr(DI_MEM_GEN_REG, Rd(DI_MEM_GEN_REG) | 0x1); + #if 0 + if (Rd_reg_bits(VIU_MISC_CTRL1, 0, 1) == 1) { + DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) & ~0x1); + dim_RDMA_WR_BITS(VD2_AFBC_ENABLE, 1, 8, 1); + } else { + DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) | 0x1); + dim_RDMA_WR_BITS(VD2_AFBC_ENABLE, 0, 8, 1); + } + #else + if (afbc_is_used()) { + dim_DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) & ~0x1); + afbc_input_sw(true); + } else { + dim_DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) | 0x1); + afbc_input_sw(false); + } + #endif + /* nrwr no clk gate en=0 */ + /*dim_RDMA_WR_BITS(DI_NRWR_CTRL, 0, 24, 1);*/ + } else { + /* nrwr no clk gate en=1 */ + /*dim_RDMA_WR_BITS(DI_NRWR_CTRL, 1, 24, 1);*/ + /* nr wr req en =0 */ + dim_RDMA_WR_BITS(DI_PRE_CTRL, 0, 0, 1); + /* disable input mif*/ + dim_DI_Wr(DI_CHAN2_GEN_REG, Rd(DI_CHAN2_GEN_REG) & ~0x1); + dim_DI_Wr(DI_MEM_GEN_REG, Rd(DI_MEM_GEN_REG) & ~0x1); + dim_DI_Wr(DI_INP_GEN_REG, Rd(DI_INP_GEN_REG) & ~0x1); + #if 0 + /* disable AFBC input */ + if (Rd_reg_bits(VIU_MISC_CTRL1, 0, 1) == 1) + dim_RDMA_WR_BITS(VD2_AFBC_ENABLE, 0, 8, 1); + #else + /* disable AFBC input */ + if (afbc_is_used()) + afbc_input_sw(false); + + #endif + } +} + +static atomic_t mif_flag; +void dimh_enable_di_pre_mif(bool en, bool mc_enable) +{ + if (atomic_read(&mif_flag)) + return; + + if (dimp_get(eDI_MP_pre_mif_gate) && !en) + return; + atomic_set(&mif_flag, 1); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_G12A)) { + if (mc_enable) + mc_pre_mif_ctrl_g12(en); + ma_pre_mif_ctrl_g12(en); + } else { + if (mc_enable) + mc_pre_mif_ctrl(en); + ma_pre_mif_ctrl(en); + } + di_pre_data_mif_ctrl(en); + atomic_set(&mif_flag, 0); +} + +void dimh_combing_pd22_window_config(unsigned int width, unsigned int height) +{ + unsigned short y1 = 39, y2 = height - 41; + + if (height >= 540) { + y1 = 79; + y2 = height - 81; + } + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) { + dim_DI_Wr_reg_bits(DECOMB_WIND00, 0, 16, 13);/* dcomb x0 */ + /* dcomb x1 */ + dim_DI_Wr_reg_bits(DECOMB_WIND00, (width - 1), 0, 13); + dim_DI_Wr_reg_bits(DECOMB_WIND01, 0, 16, 13);/* dcomb y0 */ + dim_DI_Wr_reg_bits(DECOMB_WIND01, y1, 0, 13);/* dcomb y1 */ + dim_DI_Wr_reg_bits(DECOMB_WIND10, 0, 16, 13);/* dcomb x0 */ + /* dcomb x1 */ + dim_DI_Wr_reg_bits(DECOMB_WIND10, (width - 1), 0, 13); + /* dcomb y0 */ + dim_DI_Wr_reg_bits(DECOMB_WIND11, (y1 + 1), 16, 13); + dim_DI_Wr_reg_bits(DECOMB_WIND11, y2, 0, 13);/* dcomb y1 */ + } + dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_X, 0, 0, 13);/* pd22 x0 */ + /* pd22 x1 */ + dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_X, (width - 1), 16, 13); + dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_Y, 0, 0, 13);/* pd22 y0 */ + dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND0_Y, y1, 16, 13);/* pd y1 */ + dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_X, 0, 0, 13);/* pd x0 */ + /* pd x1 */ + dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_X, (width - 1), 16, 13); + dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_Y, (y1 + 1), 0, 13);/* pd y0 */ + dim_DI_Wr_reg_bits(MCDI_PD_22_CHK_WND1_Y, y2, 16, 13);/* pd y2 */ +} + +void dimh_pulldown_vof_win_config(struct pulldown_detected_s *wins) +{ + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG0_Y, + wins->regs[0].win_vs, 17, 12); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG0_Y, + wins->regs[0].win_ve, 1, 12); + + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG1_Y, + wins->regs[1].win_vs, 17, 12); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG1_Y, + wins->regs[1].win_ve, 1, 12); + + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG2_Y, + wins->regs[2].win_vs, 17, 12); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG2_Y, + wins->regs[2].win_ve, 1, 12); + + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG3_Y, + wins->regs[3].win_vs, 17, 12); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_REG3_Y, + wins->regs[3].win_ve, 1, 12); + + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + (wins->regs[0].win_ve > wins->regs[0].win_vs) + ? 1 : 0, 16, 1); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + wins->regs[0].blend_mode, 8, 2); + + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + (wins->regs[1].win_ve > wins->regs[1].win_vs) + ? 1 : 0, 17, 1); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + wins->regs[1].blend_mode, 10, 2); + + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + (wins->regs[2].win_ve > wins->regs[2].win_vs) + ? 1 : 0, 18, 1); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + wins->regs[2].blend_mode, 12, 2); + + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + (wins->regs[3].win_ve > wins->regs[3].win_vs) + ? 1 : 0, 19, 1); + dim_VSYNC_WR_MPEG_REG_BITS(DI_BLEND_CTRL, + wins->regs[3].blend_mode, 14, 2); +} + +void dimh_load_regs(struct di_pq_parm_s *di_pq_ptr) +{ + unsigned int i = 0, j = 0, addr = 0, value = 0, mask = 0, len; + unsigned int table_name = 0, nr_table = 0; + bool ctrl_reg_flag = false; + struct am_reg_s *regs_p = NULL; + + if (dimp_get(eDI_MP_pq_load_dbg) == 1) + return; + if (dimp_get(eDI_MP_pq_load_dbg) == 2) + pr_info("[DI]%s hw load 0x%x pq table len %u.\n", + __func__, di_pq_ptr->pq_parm.table_name, + di_pq_ptr->pq_parm.table_len); + if (PTR_RET(di_pq_ptr->regs)) { + PR_ERR("[DI] table ptr error.\n"); + return; + } + pr_info("[DI]%s hw load 0x%x pq table len %u.\n", + __func__, di_pq_ptr->pq_parm.table_name, + di_pq_ptr->pq_parm.table_len); + nr_table = TABLE_NAME_NR | TABLE_NAME_DEBLOCK | TABLE_NAME_DEMOSQUITO; + regs_p = (struct am_reg_s *)di_pq_ptr->regs; + len = di_pq_ptr->pq_parm.table_len; + table_name = di_pq_ptr->pq_parm.table_name; + for (i = 0; i < len; i++) { + ctrl_reg_flag = false; + addr = regs_p->addr; + value = regs_p->val; + mask = regs_p->mask; + if (dimp_get(eDI_MP_pq_load_dbg) == 2) + pr_info("[%u][0x%x] = [0x%x]&[0x%x]\n", + i, addr, value, mask); + + for (j = 0; j < SKIP_CTRE_NUM; j++) { + if (addr == ctrl_regs[j]) + break; + } + + if (regs_p->mask != 0xffffffff) { + value = ((Rd(addr) & (~(mask))) | + (value & mask)); + } + regs_p++; + if (j < SKIP_CTRE_NUM) { + if (dimp_get(eDI_MP_pq_load_dbg) == 3) + pr_info("%s skip [0x%x]=[0x%x].\n", + __func__, addr, value); + continue; + } + if (table_name & nr_table) + ctrl_reg_flag + = get_ops_nr()->set_nr_ctrl_reg_table(addr, value); + + if (!ctrl_reg_flag) + dim_DI_Wr(addr, value); + if (dimp_get(eDI_MP_pq_load_dbg) == 2) + pr_info("[%u][0x%x] = [0x%x] %s\n", i, addr, + value, Rd(addr) != value ? "fail" : "success"); + } +} + +/*note:*/ +/* function: patch for txl for progressive source */ +/* 480p/576p/720p from hdmi will timeout */ +/* prog_flg: in: 1:progressive; */ +/* cnt: in: di_pre_stru.field_count_for_cont*/ +/* mc_en: in: mcpre_en*/ +void dimh_txl_patch_prog(int prog_flg, unsigned int cnt, bool mc_en) +{ + unsigned int di_mtn_1_ctrl1 = 0; /*ary add tmp*/ + + if (!prog_flg || !is_meson_txl_cpu()) + return; + + /*printk("prog patch\n");*/ + if (cnt >= 3) { + di_mtn_1_ctrl1 |= 1 << 29;/* enable txt */ + + if (mc_en) { + dim_RDMA_WR(DI_MTN_CTRL1, + (0xffffcfff & dim_RDMA_RD(DI_MTN_CTRL1))); + + /* enable me(mc di) */ + if (cnt == 4) { + di_mtn_1_ctrl1 &= (~(1 << 30)); + /* enable contp2rd and contprd */ + dim_RDMA_WR(MCDI_MOTINEN, 1 << 1 | 1); + } + if (cnt == 5) + dim_RDMA_WR(MCDI_CTRL_MODE, 0x1bfff7ff); + } + } else { + if (mc_en) { + /* txtdet_en mode */ + dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 1, 1); + dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 9, 1); + dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 1, 16, 1); + dim_RDMA_WR_BITS(MCDI_CTRL_MODE, 0, 28, 1); + dim_RDMA_WR(MCDI_MOTINEN, 0); + dim_RDMA_WR(DI_MTN_CTRL1, + (0xffffcfff & dim_RDMA_RD(DI_MTN_CTRL1))); + /* disable me(mc di) */ + } + dim_RDMA_WR(DNR_CTRL, 0); + } + dim_RDMA_WR(DI_MTN_1_CTRL1, di_mtn_1_ctrl1); +} + +void dim_init_setting_once(void) +{ + if (di_get_flg_hw_int()) + return; + if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXLX)) + dim_wr_cue_int(); + + di_set_flg_hw_int(true); +} + +int dim_seq_file_module_para_hw(struct seq_file *seq) +{ + seq_puts(seq, "hw---------------\n"); +#if 0 + seq_printf(seq, "%-15s:%d\n", "pq_load_dbg", pq_load_dbg); + seq_printf(seq, "%-15s:%d\n", "lmv_lock_win_en", lmv_lock_win_en); + seq_printf(seq, "%-15s:%d\n", "lmv_dist", lmv_dist); + seq_printf(seq, "%-15s:%d\n", "pr_mcinfo_cnt", pr_mcinfo_cnt); + seq_printf(seq, "%-15s:%d\n", "offset_lmv", offset_lmv); + seq_printf(seq, "%-15s:%d\n", "post_ctrl", post_ctrl); + seq_printf(seq, "%-15s:%d\n", "if2_disable", if2_disable); + seq_printf(seq, "%-15s:%d\n", "pre_flag", pre_flag); + + seq_printf(seq, "%-15s:%d\n", "pre_mif_gate", pre_mif_gate); + seq_printf(seq, "%-15s:%d\n", "pre_urgent", pre_urgent); + seq_printf(seq, "%-15s:%d\n", "pre_hold_line", pre_hold_line); + seq_printf(seq, "%-15s:%d\n", "pre_ctrl, uint", pre_ctrl); + seq_printf(seq, "%-15s:%d\n", "line_num_post_frst", + line_num_post_frst); + seq_printf(seq, "%-15s:%d\n", "line_num_pre_frst", line_num_pre_frst); + seq_printf(seq, "%-15s:%d\n", "pd22_flg_calc_en", pd22_flg_calc_en); + + /***********************/ + seq_printf(seq, "%-15s:%d\n", "mcen_mode", mcen_mode); + seq_printf(seq, "%-15s:%d\n", "mcuv_en", mcuv_en); + seq_printf(seq, "%-15s:%d\n", "mcdebug_mode", mcdebug_mode); + seq_printf(seq, "%-15s:%d\n", "pldn_ctrl_rflsh", pldn_ctrl_rflsh); +#endif + return 0; +} + diff --git a/drivers/amlogic/media/di_multi/deinterlace_hw.h b/drivers/amlogic/media/di_multi/deinterlace_hw.h new file mode 100644 index 0000000..ed00b85 --- /dev/null +++ b/drivers/amlogic/media/di_multi/deinterlace_hw.h @@ -0,0 +1,277 @@ +/* + * drivers/amlogic/media/di_multi/deinterlace_hw.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_HW_H +#define _DI_HW_H +#include + +#include "../deinterlace/di_pqa.h" + +/* if post size < 80, filter of ei can't work */ +#define MIN_POST_WIDTH 80 +#define MIN_BLEND_WIDTH 27 + +#define SKIP_CTRE_NUM 13 +/*move from deinterlace.c*/ +enum eAFBC_REG { + eAFBC_ENABLE, + eAFBC_MODE, + eAFBC_SIZE_IN, + eAFBC_DEC_DEF_COLOR, + eAFBC_CONV_CTRL, + eAFBC_LBUF_DEPTH, + eAFBC_HEAD_BADDR, + eAFBC_BODY_BADDR, + eAFBC_SIZE_OUT, + eAFBC_OUT_YSCOPE, + eAFBC_STAT, + eAFBC_VD_CFMT_CTRL, + eAFBC_VD_CFMT_W, + eAFBC_MIF_HOR_SCOPE, + eAFBC_MIF_VER_SCOPE, + eAFBC_PIXEL_HOR_SCOPE, + eAFBC_PIXEL_VER_SCOPE, + eAFBC_VD_CFMT_H, +}; + +enum eAFBC_DEC { + eAFBC_DEC0, + eAFBC_DEC1, +}; + +#define AFBC_REG_INDEX_NUB (18) +#define AFBC_DEC_NUB (2) + +struct DI_MIF_s { + unsigned short luma_x_start0; + unsigned short luma_x_end0; + unsigned short luma_y_start0; + unsigned short luma_y_end0; + unsigned short chroma_x_start0; + unsigned short chroma_x_end0; + unsigned short chroma_y_start0; + unsigned short chroma_y_end0; + unsigned int nocompress; + unsigned set_separate_en:2; + unsigned src_field_mode:1; + unsigned src_prog:1; + unsigned video_mode:1; + unsigned output_field_num:1; + unsigned bit_mode:2; + /* + * unsigned burst_size_y:2; set 3 as default + * unsigned burst_size_cb:2;set 1 as default + * unsigned burst_size_cr:2;set 1 as default + */ + unsigned canvas0_addr0:8; + unsigned canvas0_addr1:8; + unsigned canvas0_addr2:8; +}; + +struct DI_SIM_MIF_s { + unsigned short start_x; + unsigned short end_x; + unsigned short start_y; + unsigned short end_y; + unsigned short canvas_num; + unsigned short bit_mode; +}; + +struct DI_MC_MIF_s { + unsigned short start_x; + unsigned short start_y; + unsigned short end_y; + unsigned short size_x; + unsigned short size_y; + unsigned short canvas_num; + unsigned short blend_en; + unsigned short vecrd_offset; +}; + +enum gate_mode_e { + GATE_AUTO, + GATE_ON, + GATE_OFF, +}; + +struct mcinfo_lmv_s { + unsigned char lock_flag; + char lmv; + unsigned short lock_cnt; +}; + +struct di_pq_parm_s { + struct am_pq_parm_s pq_parm; + struct am_reg_s *regs; + struct list_head list; +}; + +void dim_read_pulldown_info(unsigned int *glb_frm_mot_num, + unsigned int *glb_fid_mot_num); + +#if 0 + +void read_new_pulldown_info(struct FlmModReg_t *pFMRegp); +#endif +void dim_pulldown_info_clear_g12a(void); +void dimh_combing_pd22_window_config(unsigned int width, unsigned int height); +void dimh_hw_init(bool pulldown_en, bool mc_enable); +void dimh_hw_uninit(void); +void dimh_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, + struct DI_SIM_MIF_s *di_contp2rd_mif, + struct DI_SIM_MIF_s *di_contprd_mif, + struct DI_SIM_MIF_s *di_contwr_mif, + unsigned char madi_en, + unsigned char pre_field_num, + unsigned char pre_vdin_link); +void dimh_enable_afbc_input(struct vframe_s *vf); + +void dimh_mc_pre_mv_irq(void); +void dimh_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, + unsigned char mcdi_en); +void dimh_enable_mc_di_pre_g12(struct DI_MC_MIF_s *di_mcinford_mif, + struct DI_MC_MIF_s *di_mcinfowr_mif, + struct DI_MC_MIF_s *di_mcvecwr_mif, + unsigned char mcdi_en); + +void dimh_enable_mc_di_post(struct DI_MC_MIF_s *di_mcvecrd_mif, + int urgent, bool reverse, int invert_mv); +void dimh_enable_mc_di_post_g12(struct DI_MC_MIF_s *di_mcvecrd_mif, + int urgent, bool reverse, int invert_mv); + +void dimh_disable_post_deinterlace_2(void); +void dimh_initial_di_post_2(int hsize_post, int vsize_post, + int hold_line, bool write_en); +void dimh_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 invert_mv, int vskip_cnt +); +void dimh_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 invert_mv, bool pd_en, bool mc_enable, + int vskip_cnt +); +void dim_post_read_reverse_irq(bool reverse, + unsigned char mc_pre_flag, bool mc_enable); +void dim_top_gate_control(bool top_en, bool mc_en); +void dim_pre_gate_control(bool enable, bool mc_enable); +void dim_post_gate_control(bool gate); +void dim_set_power_control(unsigned char enable); +void dim_hw_disable(bool mc_enable); +void dimh_enable_di_pre_mif(bool enable, bool mc_enable); +void dimh_enable_di_post_mif(enum gate_mode_e mode); + +void dimh_combing_pd22_window_config(unsigned int width, unsigned int height); +void dimh_calc_lmv_init(void); +void dimh_calc_lmv_base_mcinfo(unsigned int vf_height, + unsigned long mcinfo_adr, + unsigned int mcinfo_size); +void dimh_init_field_mode(unsigned short height); +void dim_film_mode_win_config(unsigned int width, unsigned int height); +void dimh_pulldown_vof_win_config(struct pulldown_detected_s *wins); +void dimh_load_regs(struct di_pq_parm_s *di_pq_ptr); +void dim_pre_frame_reset_g12(unsigned char madi_en, unsigned char mcdi_en); +void dim_pre_frame_reset(void); +void dimh_interrupt_ctrl(unsigned char ma_en, + unsigned char det3d_en, unsigned char nrds_en, + unsigned char post_wr, unsigned char mc_en); +void dimh_txl_patch_prog(int prog_flg, unsigned int cnt, bool mc_en); +bool dimh_afbc_is_supported(void); + +void dimh_afbc_reg_sw(bool on); + +void dump_vd2_afbc(void); + +u8 *dim_vmap(ulong addr, u32 size, bool *bflg); +void dim_unmap_phyaddr(u8 *vaddr); +int dim_print(const char *fmt, ...); + +#define DI_MC_SW_OTHER (1 << 0) +#define DI_MC_SW_REG (1 << 1) +/*#define DI_MC_SW_POST (1 << 2)*/ +#define DI_MC_SW_IC (1 << 2) + +#define DI_MC_SW_ON_MASK (DI_MC_SW_REG | DI_MC_SW_OTHER | DI_MC_SW_IC) + +void dimh_patch_post_update_mc(void); +void dimh_patch_post_update_mc_sw(unsigned int cmd, bool on); + +void dim_rst_protect(bool on); +void dim_pre_nr_wr_done_sel(bool on); +void dim_arb_sw(bool on); +void dbg_set_DI_PRE_CTRL(void); +void di_async_reset2(void); /*2019-04-05 add for debug*/ + +enum DI_HW_POST_CTRL { + DI_HW_POST_CTRL_INIT, + DI_HW_POST_CTRL_RESET, +}; + +void dimh_post_ctrl(enum DI_HW_POST_CTRL contr, + unsigned int post_write_en); +void dimh_int_ctr(unsigned int set_mod, unsigned char ma_en, + unsigned char det3d_en, unsigned char nrds_en, + unsigned char post_wr, unsigned char mc_en); + +void h_dbg_reg_set(unsigned int val); + +enum eDI_POST_FLOW { + eDI_POST_FLOW_STEP1_STOP, + eDI_POST_FLOW_STEP2_START, +/* eDI_POST_FLOW_STEP3_RESET_INT,*/ +}; + +void di_post_set_flow(unsigned int post_wr_en, enum eDI_POST_FLOW step); +void post_mif_sw(bool on); +void post_dbg_contr(void); +void post_close_new(void); +void di_post_reset(void); +void dimh_pst_trig_resize(void); + +void hpst_power_ctr(bool on); +void hpst_dbg_power_ctr_trig(unsigned int cmd); +void hpst_dbg_mem_pd_trig(unsigned int cmd); +void hpst_dbg_trig_gate(unsigned int cmd); +void hpst_dbg_trig_mif(unsigned int cmd); +void hpst_mem_pd_sw(unsigned int on); +void hpst_vd1_sw(unsigned int on); + +void dim_init_setting_once(void); +void dim_hw_init_reg(void); + +#endif diff --git a/drivers/amlogic/media/di_multi/di_api.c b/drivers/amlogic/media/di_multi/di_api.c new file mode 100644 index 0000000..554bdf1 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_api.c @@ -0,0 +1,106 @@ +/* + * drivers/amlogic/media/di_multi/di_api.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 "di_api.h" +/********************************** + * DI api is used for other module + *********************************/ +static const struct di_ext_ops di_ext = { + .di_post_reg_rd = l_DI_POST_REG_RD, + .di_post_wr_reg_bits = l_DI_POST_WR_REG_BITS, +}; + +void dim_attach_to_local(void) +{ + dil_attach_ext_api(&di_ext); +} + +bool dim_attach_ext_api(struct di_ext_ops *di_api) +{ + #if 1 + if (!di_api) + return false; + + memcpy(di_api, &di_ext, sizeof(struct di_ext_ops)); + #else + di_api = &di_ext; + #endif + return true; +} + +/*EXPORT_SYMBOL(dim_attach_ext_api);*/ + +/********************************** + * ext_api used by DI + ********************************/ +#define ARY_TEMP2 +#ifdef ARY_TEMP2 +void ext_switch_vpu_mem_pd_vmod(unsigned int vmod, bool on) +{ + switch_vpu_mem_pd_vmod(vmod, + on ? VPU_MEM_POWER_ON : VPU_MEM_POWER_DOWN); +} + +const struct ext_ops_s ext_ops = { + .switch_vpu_mem_pd_vmod = ext_switch_vpu_mem_pd_vmod, + /*no use ?*/ +/* .vf_get_receiver_name = vf_get_receiver_name,*/ + .switch_vpu_clk_gate_vmod = switch_vpu_clk_gate_vmod, + .get_current_vscale_skip_count = get_current_vscale_skip_count, + .canvas_pool_alloc_canvas_table = canvas_pool_alloc_canvas_table, +}; + +#else +void n_switch_vpu_mem_pd_vmod(unsigned int vmod, bool on) +{ +} + +char *n_vf_get_receiver_name(const char *provider_name) +{ + return ""; +} + +void n_switch_vpu_clk_gate_vmod(unsigned int vmod, int flag) +{ +} + +int n_get_current_vscale_skip_count(struct vframe_s *vf) +{ + return 0; +} + +u32 n_canvas_pool_alloc_canvas_table(const char *owner, u32 *tab, + int size, + enum canvas_map_type_e type) +{ + return 0; +} + +const struct ext_ops_s ext_ops = { + .switch_vpu_mem_pd_vmod = n_switch_vpu_mem_pd_vmod, + .vf_get_receiver_name = n_vf_get_receiver_name, + .switch_vpu_clk_gate_vmod = n_switch_vpu_clk_gate_vmod, + .get_current_vscale_skip_count = n_get_current_vscale_skip_count, + .canvas_pool_alloc_canvas_table = n_canvas_pool_alloc_canvas_table, +}; + +#endif + diff --git a/drivers/amlogic/media/di_multi/di_api.h b/drivers/amlogic/media/di_multi/di_api.h new file mode 100644 index 0000000..0cd08de --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_api.h @@ -0,0 +1,55 @@ +/* + * drivers/amlogic/media/di_multi/di_api.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_API_H__ +#define __DI_API_H__ + +#include +#include +#include "../di_local/di_local.h" + +/*--------------------------*/ +unsigned int l_DI_POST_REG_RD(unsigned int addr); +int l_DI_POST_WR_REG_BITS(u32 adr, u32 val, u32 start, u32 len); + +/*--------------------------*/ +bool di_attach_ext_api(struct di_ext_ops *di_api); + +/*attach di_ops to di_local*/ +bool dil_attach_ext_api(const struct di_ext_ops *di_api); +void dim_attach_to_local(void); + +/*--------------------------*/ +int get_current_vscale_skip_count(struct vframe_s *vf); + +struct ext_ops_s { + void (*switch_vpu_mem_pd_vmod)(unsigned int vmod, bool on); +/* char *(*vf_get_receiver_name)(const char *provider_name);*/ + void (*switch_vpu_clk_gate_vmod)(unsigned int vmod, int flag); + int (*get_current_vscale_skip_count)(struct vframe_s *vf); + u32 (*canvas_pool_alloc_canvas_table)(const char *owner, u32 *tab, + int size, + enum canvas_map_type_e type); +}; + +extern const struct ext_ops_s ext_ops; + +/*--------------------------*/ +void dil_get_rev_mem(unsigned long *mstart, unsigned int *msize); +void dil_get_flg(unsigned int *flg); + +#endif /*__DI_API_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_data.h b/drivers/amlogic/media/di_multi/di_data.h new file mode 100644 index 0000000..d9ddb8f --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_data.h @@ -0,0 +1,21 @@ +/* + * drivers/amlogic/media/di_multi/di_data.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_DATA_H__ +#define __DI_DATA_H__ + +#endif /*__DI_DATA_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_data_l.h b/drivers/amlogic/media/di_multi/di_data_l.h new file mode 100644 index 0000000..82a6682 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_data_l.h @@ -0,0 +1,1372 @@ +/* + * drivers/amlogic/media/di_multi/di_data_l.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_DATA_L_H__ +#define __DI_DATA_L_H__ + +#include +#include +#include + +#include /*ary add*/ + +#include "../deinterlace/di_pqa.h" + +#define DI_CHANNEL_NUB (2) +#define DI_CHANNEL_MAX (4) + +#define TABLE_FLG_END (0xfffffffe) +#define TABLE_LEN_MAX (1000) +#define F_IN(x, a, b) (((x) > (a)) && ((x) < (b))) +#define COM_M(m, a, b) (((a) & (m)) == ((b) & (m))) +#define COM_MV(a, m, v) (((a) & (m)) == (v)) +#define COM_ME(a, m) (((a) & (m)) == (m)) + +#define DI_BIT0 0x01 +#define DI_BIT1 0x02 +#define DI_BIT2 0x04 +#define DI_BIT3 0x08 + +/***************************************** + * + * vframe mask + * + *****************************************/ + +#define DI_VFM_T_MASK_CHANGE \ + (VIDTYPE_VIU_422 \ + | VIDTYPE_VIU_SINGLE_PLANE \ + | VIDTYPE_VIU_444 \ + | VIDTYPE_INTERLACE \ + | VIDTYPE_COMPRESS \ + | VIDTYPE_MVC) + +/* ************************************** */ +/* *************** cfg top ************** */ +/* ************************************** */ +/* also see: di_cfg_top_ctr*/ +enum eDI_CFG_TOP_IDX { + /* cfg for top */ + eDI_CFG_BEGIN, + eDI_CFG_first_bypass, + eDI_CFG_ref_2, + eDI_CFG_END, + +}; + +#define K_DI_CFG_NUB (eDI_CFG_END - eDI_CFG_BEGIN + 1) +struct di_cfg_ctr_s { + char *name; + enum eDI_CFG_TOP_IDX id; + bool default_val; +}; + +/* ************************************** */ +/* *************** cfg x *************** */ +/* ************************************** */ +/*also see di_cfgx_ctr*/ +enum eDI_CFGX_IDX { + /* cfg channel x*/ + eDI_CFGX_BEGIN, + eDI_CFGX_BYPASS_ALL, /*bypass_all*/ + eDI_CFGX_END, + + /* debug cfg x */ + eDI_DBG_CFGX_BEGIN, + eDI_DBG_CFGX_IDX_VFM_IN, + eDI_DBG_CFGX_IDX_VFM_OT, + eDI_DBG_CFGX_END, +}; + +#define K_DI_CFGX_NUB (eDI_DBG_CFGX_END - eDI_CFGX_BEGIN + 1) + +struct di_cfgx_ctr_s { + char *name; + enum eDI_CFGX_IDX id; + bool default_val; +}; + +/* ****************************** */ +enum eDI_SUB_ID { + DI_SUB_ID_S0, /*DI_SUB_ID_MARST,*/ + DI_SUB_ID_S1, + DI_SUB_ID_S2, + DI_SUB_ID_S3, + /*DI_SUB_ID_NUB,*/ +}; + +/*debug vframe type */ +struct di_vframe_type_info { + char *name; + unsigned int mask; + char *other; +}; + +struct di_dbg_datax_s { + struct vframe_s vfm_input; /*debug input vframe*/ + struct vframe_s *pfm_out; /*debug di_get vframe*/ + +}; + +/*debug function*/ +enum eDI_DBG_F { + eDI_DBG_F_00, + eDI_DBG_F_01, + eDI_DBG_F_02, + eDI_DBG_F_03, + eDI_DBG_F_04, + eDI_DBG_F_05, + eDI_DBG_F_06, + eDI_DBG_F_07, + eDI_DBG_F_08, +}; + +struct di_dbg_func_s { + enum eDI_DBG_F index; + void (*func)(unsigned int para); + char *name; + char *info; +}; + +/*register*/ +struct reg_t { + unsigned int add; + unsigned int bit; + unsigned int wid; +/* unsigned int id;*/ + unsigned int df_val; + char *name; + char *bname; + char *info; +}; + +struct reg_acc { + void (*wr)(unsigned int adr, unsigned int val); + unsigned int (*rd)(unsigned int adr); + unsigned int (*bwr)(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len); + unsigned int (*brd)(unsigned int adr, unsigned int start, + unsigned int len); +}; + +/**************************************/ +/* time out */ +/**************************************/ + +enum eDI_TOUT_CONTR { +/* eDI_TOUT_CONTR_INT,*/ + eDI_TOUT_CONTR_EN, + eDI_TOUT_CONTR_FINISH, + eDI_TOUT_CONTR_CHECK, + + eDI_TOUT_CONTR_CLEAR, + eDI_TOUT_CONTR_RESET, +}; + +struct di_time_out_s { + bool en; + unsigned long timer_start; + unsigned int timer_thd; + unsigned int over_flow_cnt; + bool flg_over; +/* bool (*do_func)(void);*/ +}; + +struct di_func_tab_s { + unsigned int index; + bool (*func)(void); +}; + +/****************************************/ +/* do_table */ +/****************************************/ + +/*for do_table_ops_s id*/ +#define K_DO_TABLE_ID_PAUSE 0 +#define K_DO_TABLE_ID_STOP 1 +#define K_DO_TABLE_ID_START 2 + +/*for mark of do_table_ops_s id*/ +#define K_DO_TABLE_CAN_STOP 0x01 + +/*for op ret*/ +#define K_DO_TABLE_R_B_FINISH 0x01/*bit 0: 0:not finish, 1:finish*/ +/*bit 1: 0: to other index; 1: to next*/ +#define K_DO_TABLE_R_B_NEXT 0x02 +#define K_DO_TABLE_R_B_OTHER 0xf0 /*bit [7:4]: other index*/ +#define K_DO_TABLE_R_B_OTHER_SHIFT 4 /*bit [7:4]: other index*/ + +#define K_DO_R_FINISH (K_DO_TABLE_R_B_FINISH | K_DO_TABLE_R_B_NEXT) +#define K_DO_R_NOT_FINISH (0) +#define K_DO_R_JUMP(a) (K_DO_TABLE_R_B_FINISH | \ + (((a) << K_DO_TABLE_R_B_OTHER_SHIFT) & K_DO_TABLE_R_B_OTHER)) + +enum eDO_TABLE_CMD { + eDO_TABLE_CMD_NONE, + eDO_TABLE_CMD_STOP, + eDO_TABLE_CMD_START, + eDO_TABLE_CMD_PAUSE, + eDO_TABLE_CMD_STEP, + eDO_TABLE_CMD_STEP_BACK, +}; + +struct do_table_ops_s { + /*bool stop_mark;*/ + unsigned int id; + unsigned int mark; /*stop / pause*/ + bool (*con)(void *data);/*condition*/ + unsigned int (*do_op)(void *data); + unsigned int (*do_stop_op)(void *data); + char *name; + +}; + +struct do_table_s { + const struct do_table_ops_s *ptab; + unsigned int size; + unsigned int op_lst; + unsigned int op_crr; + void *data; + bool do_stop; /*need do stops */ + bool flg_stop; /*have stop */ + + bool do_pause; + bool do_step; /*step mode*/ + + bool flg_repeat; + char *name; + +}; + +/*************************************/ + +/**********************/ +/* vframe info */ +/**********************/ +struct di_vinfo_s { + /*use this for judge type change or not */ + unsigned int ch; + unsigned int vtype; + unsigned int src_type; + unsigned int trans_fmt; + unsigned int h; + unsigned int v; +}; + +/**************************************/ +/* PRE */ +/**************************************/ +enum eDI_PRE_ST { + eDI_PRE_ST_EXIT, + eDI_PRE_ST_IDLE, /*swith to next channel?*/ + eDI_PRE_ST_CHECK, + eDI_PRE_ST_SET, + eDI_PRE_ST_WAIT_INT, + eDI_PRE_ST_TIMEOUT, +}; + +enum eDI_PRE_ST4 { /*use this for co work with do table*/ + eDI_PRE_ST4_EXIT, + eDI_PRE_ST4_IDLE, /*swith to next channel?*/ + eDI_PRE_ST4_CHECK, /*check mode do_table and set*/ + eDI_PRE_ST4_DO_TABLE, /* do table statue;*/ +}; + +struct di_pre_set_s { + /*use to remember last hw pre setting;*/ + /*cfg: */ + bool cfg_mcpre_en; /*mcpre_en*/ + + unsigned int in_w; + unsigned int in_h; + unsigned int in_type; + unsigned int src_type; +}; + +struct di_hpre_s { + enum eDI_PRE_ST4 pre_st; + unsigned int curr_ch; + /*set when have vframe in; clear when int have get*/ + bool hw_flg_busy_pre; +/* bool trig_unreg;*/ /*add for unreg flow;*/ +/* enum eDI_SUB_ID hw_owner_pre;*/ + bool flg_wait_int; + struct di_pre_stru_s *pres; + struct di_post_stru_s *psts; + struct di_time_out_s tout; /*for time out*/ + bool flg_int_done; + unsigned int check_recycle_buf_cnt; + + struct di_pre_set_s set_lst; + struct di_pre_set_s set_curr; + + struct di_vinfo_s vinf_lst; + struct di_vinfo_s vinf_curr; + + /* use do table to swith mode*/ + struct do_table_s sdt_mode; + + unsigned int idle_cnt; /*use this avoid repeat idle <->check*/ + /*dbg flow:*/ + bool dbg_f_en; + unsigned int dbg_f_lstate; + unsigned int dbg_f_cnt; +}; + +/**************************************/ +/* POST */ +/**************************************/ +enum eDI_PST_ST { + eDI_PST_ST_EXIT, + eDI_PST_ST_IDLE, /*swith to next channel?*/ + eDI_PST_ST_CHECK, + eDI_PST_ST_SET, + eDI_PST_ST_WAIT_INT, + eDI_PST_ST_TIMEOUT, + eDI_PST_ST_DONE, /*use for bypass_all*/ +}; + +struct di_hpst_s { + enum eDI_PST_ST state; + unsigned int curr_ch; + /*set when have vframe in; clear when int have get*/ + bool hw_flg_busy_post; + struct di_pre_stru_s *pres; + struct di_post_stru_s *psts; + struct di_time_out_s tout; /*for time out*/ + bool flg_int_done; + + /*dbg flow:*/ + bool dbg_f_en; + unsigned int dbg_f_lstate; + unsigned int dbg_f_cnt; + +}; + +/**************************************/ +/* channel status */ +/**************************************/ +enum eDI_TOP_STATE { + eDI_TOP_STATE_NOPROB, + eDI_TOP_STATE_IDLE, /*idle not work*/ + /* STEP1 + * till peek vframe and set irq;before this state, event reg finish + */ + eDI_TOP_STATE_REG_STEP1, + eDI_TOP_STATE_REG_STEP1_P1, /*2019-05-21*/ + eDI_TOP_STATE_REG_STEP2, /*till alloc and ready*/ + eDI_TOP_STATE_READY, /*can do DI*/ + eDI_TOP_STATE_BYPASS, /*complet bypass*/ + eDI_TOP_STATE_UNREG_STEP1, /*till pre/post is finish;*/ + /* do unreg and to IDLE. + * no need to wait cma release after this unreg event finish + */ + eDI_TOP_STATE_UNREG_STEP2, + +}; + +/**************************************/ +/* thread and cmd */ +/**************************************/ +struct di_task { + bool flg_init; + struct semaphore sem; + wait_queue_head_t wait_queue; + struct task_struct *thread; + unsigned int status; + + unsigned int wakeup; + unsigned int delay; + bool exit; +#if 1 /*not use cmd*/ + + /*local event*/ + struct kfifo fifo_cmd; + spinlock_t lock_cmd; + bool flg_cmd; + unsigned int err_cmd_cnt; +#endif +}; + +#define MAX_KFIFO_L_CMD_NUB 32 + +union DI_L_CMD_BITS { + unsigned int cmd32; + struct { + unsigned int id:8, /*low bit*/ + ch:8, /*channel*/ + p2:8, + p3:8; + } b; +}; + +#define LCMD1(id, ch) ((id) | ((ch) << 8)) + +enum eCMD_LOCAL { + eCMD_NONE, + eCMD_REG, + eCMD_UNREG, + eCMD_READY, + eCMD_CHG, + NR_FINISH, +}; + +/**************************************/ +/*QUE*/ +/**************************************/ +enum QUE_TYPE { /*mast start from 0 */ + QUE_IN_FREE, /*5*/ + QUE_PRE_READY, /*6*/ + QUE_POST_FREE, /*7*/ + QUE_POST_READY, /*8*/ + QUE_POST_BACK, /*new*/ + /*----------------*/ + QUE_DBG, + QUE_NUB, +}; + +/*#define QUE_NUB (5)*/ +enum eDI_BUF_TYPE { + eDI_BUF_T_IN = 1, /*VFRAME_TYPE_IN*/ + eDI_BUF_T_LOCAL, /*VFRAME_TYPE_LOCAL*/ + eDI_BUF_T_POST, /*VFRAME_TYPE_POST*/ +}; + +#define MAX_FIFO_SIZE (32) + +/************************************** + * + * summmary variable + * also see:di_sum_name_tab + **************************************/ + +enum eDI_SUM { + eDI_SUM_O_PEEK_CNT, /*video_peek_cnt*/ + eDI_SUM_REG_UNREG_CNT, /*di_reg_unreg_cnt*/ + eDI_SUM_NUB, +}; + +struct di_sum_s { + char *name; + enum eDI_SUM index; + unsigned int default_val; +}; + +/************************************** + * + * module para + * int + * eDI_MP_SUB_DI_B + * eDI_MP_SUB_NR_B + * eDI_MP_SUB_PD_B + * eDI_MP_SUB_MTN_B + * eDI_MP_SUB_3D_B + **************************************/ +enum eDI_MP_UI_T { + /*keep same order with di_mp_ui_top*/ + eDI_MP_UI_T_BEGIN, + /**************************************/ + eDI_MP_SUB_DI_B, + + eDI_MP_force_prog, /*force_prog bool*/ + eDI_MP_combing_fix_en, /*combing_fix_en bool*/ + eDI_MP_cur_lev, /*cur_lev*/ + eDI_MP_pps_dstw, /*pps_dstw*/ + eDI_MP_pps_dsth, /*pps_dsth*/ + eDI_MP_pps_en, /*pps_en*/ + eDI_MP_pps_position, /*pps_position*/ + eDI_MP_pre_enable_mask, /*pre_enable_mask*/ + eDI_MP_post_refresh, /*post_refresh*/ + eDI_MP_nrds_en, /*nrds_en*/ + eDI_MP_bypass_3d, /*bypass_3d*/ + eDI_MP_bypass_trick_mode, /*bypass_trick_mode*/ + eDI_MP_invert_top_bot, /*invert_top_bot */ + eDI_MP_skip_top_bot, + eDI_MP_force_width, + eDI_MP_force_height, + eDI_MP_prog_proc_config, + eDI_MP_start_frame_drop_count, + eDI_MP_same_field_top_count, /*long?*/ + eDI_MP_same_field_bot_count, /*long?*/ + eDI_MP_vpp_3d_mode, + eDI_MP_force_recovery_count, + eDI_MP_pre_process_time, /*no use?*/ + eDI_MP_bypass_post, + eDI_MP_post_wr_en, + eDI_MP_post_wr_support, + eDI_MP_bypass_post_state, + eDI_MP_use_2_interlace_buff, + eDI_MP_debug_blend_mode, + eDI_MP_nr10bit_support, + eDI_MP_di_stop_reg_flag, + eDI_MP_mcpre_en, + eDI_MP_check_start_drop_prog, + eDI_MP_overturn, /*? in init*/ + eDI_MP_full_422_pack, + eDI_MP_cma_print, + eDI_MP_pulldown_enable, + eDI_MP_di_force_bit_mode, + eDI_MP_calc_mcinfo_en, + eDI_MP_colcfd_thr, + eDI_MP_post_blend, + eDI_MP_post_ei, + eDI_MP_post_cnt, + eDI_MP_di_log_flag, + eDI_MP_di_debug_flag, + eDI_MP_buf_state_log_threshold, + eDI_MP_di_vscale_skip_enable, + eDI_MP_di_vscale_skip_count, + eDI_MP_di_vscale_skip_count_real, + eDI_MP_det3d_en, + eDI_MP_post_hold_line, + eDI_MP_post_urgent, + eDI_MP_di_printk_flag, + eDI_MP_force_recovery, +/* eDI_MP_debug_blend_mode,*/ + eDI_MP_di_dbg_mask, + eDI_MP_nr_done_check_cnt, + eDI_MP_pre_hsc_down_en, + eDI_MP_pre_hsc_down_width, + eDI_MP_show_nrwr, + /********deinterlace_hw.c*********/ + eDI_MP_pq_load_dbg, + eDI_MP_lmv_lock_win_en, + eDI_MP_lmv_dist, + eDI_MP_pr_mcinfo_cnt, + eDI_MP_offset_lmv, + eDI_MP_post_ctrl, + eDI_MP_if2_disable, + eDI_MP_pre_flag, + eDI_MP_pre_mif_gate, + eDI_MP_pre_urgent, + eDI_MP_pre_hold_line, + eDI_MP_pre_ctrl, + eDI_MP_line_num_post_frst, + eDI_MP_line_num_pre_frst, + eDI_MP_pd22_flg_calc_en, + eDI_MP_mcen_mode, + eDI_MP_mcuv_en, + eDI_MP_mcdebug_mode, + eDI_MP_pldn_ctrl_rflsh, + + eDI_MP_SUB_DI_E, + /**************************************/ + eDI_MP_SUB_NR_B, + eDI_MP_dnr_en, + eDI_MP_nr2_en, + eDI_MP_cue_en, + eDI_MP_invert_cue_phase, + eDI_MP_cue_pr_cnt, + eDI_MP_cue_glb_mot_check_en, + eDI_MP_glb_fieldck_en, + eDI_MP_dnr_pr, + eDI_MP_dnr_dm_en, + eDI_MP_SUB_NR_E, + /**************************************/ + eDI_MP_SUB_PD_B, + eDI_MP_flm22_ratio, + eDI_MP_pldn_cmb0, + eDI_MP_pldn_cmb1, + eDI_MP_flm22_sure_num, + eDI_MP_flm22_glbpxlnum_rat, + eDI_MP_flag_di_weave, + eDI_MP_flm22_glbpxl_maxrow, + eDI_MP_flm22_glbpxl_minrow, + eDI_MP_cmb_3point_rnum, + eDI_MP_cmb_3point_rrat, + /******film_fw1.c**/ + eDI_MP_pr_pd, + eDI_MP_prt_flg, + eDI_MP_flmxx_maybe_num, + eDI_MP_flm32_mim_frms, + eDI_MP_flm22_dif01a_flag, + eDI_MP_flm22_mim_frms, + eDI_MP_flm22_mim_smfrms, + eDI_MP_flm32_f2fdif_min0, + eDI_MP_flm32_f2fdif_min1, + eDI_MP_flm32_chk1_rtn, + eDI_MP_flm32_ck13_rtn, + eDI_MP_flm32_chk2_rtn, + eDI_MP_flm32_chk3_rtn, + eDI_MP_flm32_dif02_ratio, + eDI_MP_flm22_chk20_sml, + eDI_MP_flm22_chk21_sml, + eDI_MP_flm22_chk21_sm2, + eDI_MP_flm22_lavg_sft, + eDI_MP_flm22_lavg_lg, + eDI_MP_flm22_stl_sft, + eDI_MP_flm22_chk5_avg, + eDI_MP_flm22_chk6_max, + eDI_MP_flm22_anti_chk1, + eDI_MP_flm22_anti_chk3, + eDI_MP_flm22_anti_chk4, + eDI_MP_flm22_anti_ck140, + eDI_MP_flm22_anti_ck141, + eDI_MP_flm22_frmdif_max, + eDI_MP_flm22_flddif_max, + eDI_MP_flm22_minus_cntmax, + eDI_MP_flagdif01chk, + eDI_MP_dif01_ratio, + /*******vof_soft_top*****/ + eDI_MP_cmb32_blw_wnd, + eDI_MP_cmb32_wnd_ext, + eDI_MP_cmb32_wnd_tol, + eDI_MP_cmb32_frm_nocmb, + eDI_MP_cmb32_min02_sft, + eDI_MP_cmb32_cmb_tol, + eDI_MP_cmb32_avg_dff, + eDI_MP_cmb32_smfrm_num, + eDI_MP_cmb32_nocmb_num, + eDI_MP_cmb22_gcmb_rnum, + eDI_MP_flmxx_cal_lcmb, + eDI_MP_flm2224_stl_sft, + eDI_MP_SUB_PD_E, + /**************************************/ + eDI_MP_SUB_MTN_B, + eDI_MP_force_lev, + eDI_MP_dejaggy_flag, + eDI_MP_dejaggy_enable, + eDI_MP_cmb_adpset_cnt, + eDI_MP_cmb_num_rat_ctl4, + eDI_MP_cmb_rat_ctl4_minthd, + eDI_MP_small_local_mtn, + eDI_MP_di_debug_readreg, + eDI_MP_SUB_MTN_E, + /**************************************/ + eDI_MP_SUB_3D_B, + eDI_MP_chessbd_vrate, + eDI_MP_det3d_debug, + + eDI_MP_SUB_3D_E, + /**************************************/ + eDI_MP_UI_T_END, +}; + +#define K_DI_MP_UIT_NUB (eDI_MP_UI_T_END - eDI_MP_UI_T_BEGIN + 1) + +struct di_mp_uit_s { + char *name; + enum eDI_MP_UI_T id; + int default_val; +}; + +/*also see: di_mpx*/ +enum eDI_MP_UIX_T { + eDI_MP_UIX_BEGIN, + eDI_MP_UIX_RUN_FLG, /*run_flag*/ + eDI_MP_UIX_END, +}; + +#define K_DI_MP_UIX_NUB (eDI_MP_UIX_END - eDI_MP_UIX_BEGIN + 1) + +struct di_mp_uix_s { + char *name; + enum eDI_MP_UIX_T id; + unsigned int default_val; +}; + +/**************************************/ +/* DI WORKING MODE */ +/**************************************/ +enum eDI_WORK_MODE { + eDI_WORK_MODE_NONE, + eDI_WORK_MODE_bypass_complet, + eDI_WORK_MODE_bypass_all, /*dim_is_bypass*/ + eDI_WORK_MODE_bypass_pre, + eDI_WORK_MODE_bypass_post, + eDI_WORK_MODE_i, + eDI_WORK_MODE_p_as_i, + eDI_WORK_MODE_p_as_p, + eDI_WORK_MODE_p_use_ibuf, + eDI_WORK_MODE_all, + +}; + +/**************************************/ +/* vframe */ +/**************************************/ +struct dev_vfram_t { + const char *name; + /*receiver:*/ + struct vframe_receiver_s di_vf_recv; + /*provider:*/ + struct vframe_provider_s di_vf_prov; + + unsigned int indx; + /*status:*/ + bool bypass_complete; + bool reg; /*use this for vframe reg/unreg*/ +/* unsigned int data[32]; */ /*null*/ + +}; + +struct di_ores_s { + /* same as ori */ + struct di_pre_stru_s di_pre_stru; + struct di_post_stru_s di_post_stru; + + struct di_buf_s di_buf_local[MAX_LOCAL_BUF_NUM * 2]; + struct di_buf_s di_buf_in[MAX_IN_BUF_NUM]; + struct di_buf_s di_buf_post[MAX_POST_BUF_NUM]; + + struct queue_s queue[QUEUE_NUM]; + struct di_buf_pool_s di_buf_pool[VFRAME_TYPE_NUM]; + + struct vframe_s *vframe_in[MAX_IN_BUF_NUM]; + struct vframe_s vframe_in_dup[MAX_IN_BUF_NUM]; + struct vframe_s vframe_local[MAX_LOCAL_BUF_NUM * 2]; + struct vframe_s vframe_post[MAX_POST_BUF_NUM]; + /* ********** */ +}; + +enum eDI_CMA_ST { + eDI_CMA_ST_IDL, + eDI_CMA_ST_ALLOC, /*do*/ + eDI_CMA_ST_READY, + eDI_CMA_ST_RELEASE, /*do*/ +}; + +/********************************** + * mem + *********************************/ +struct di_mm_cfg_s { + /*support di size*/ + unsigned int di_h; + unsigned int di_w; + /**/ + unsigned int num_local; + unsigned int num_post; +}; + +struct di_mm_st_s { + /* use for reserved and alloc all*/ + unsigned long mem_start; + unsigned int mem_size; + struct page *total_pages; + + unsigned int flag_cma; + + unsigned int size_local; + unsigned int size_post; + int num_local; + int num_post; /*ppost*/ +}; + +struct di_mm_s { + struct di_mm_cfg_s cfg; + struct di_mm_st_s sts; +}; + +struct di_ch_s { + /*struct di_cfgx_s dbg_cfg;*/ + bool cfgx_en[K_DI_CFGX_NUB]; + unsigned int mp_uix[K_DI_MP_UIX_NUB];/*module para x*/ + + struct di_dbg_datax_s dbg_data; + + struct dev_vfram_t vfm; + struct dentry *dbg_rootx; /*dbg_fs*/ + + unsigned int ch_id; + struct di_ores_s rse_ori; + struct kfifo fifo[QUE_NUB]; + bool flg_fifo[QUE_NUB]; /*have ini: 1; else 0*/ +/* bool sub_act_flg;*/ + /************************/ + /*old glob*/ + /************************/ + /*bypass_state*/ + bool bypass_state; + + /*video_peek_cnt*/ + unsigned int sum[eDI_SUM_NUB + 1]; + unsigned int sum_get; + unsigned int sum_put; + +}; + +struct di_meson_data { + const char *name; + /*struct ic_ver icver;*/ + /*struct ddemod_reg_off regoff;*/ +}; + +struct di_mng_s { + /*workqueue*/ + struct workqueue_struct *wq_cma; + struct work_struct wq_work; + + /*use enum eDI_CMA_ST*/ + atomic_t cma_mem_state[DI_CHANNEL_NUB]; + /*1:alloc cma, 0:release cma set by mng, read by work que*/ + unsigned char cma_reg_cmd[DI_CHANNEL_NUB]; + + /*task:*/ + struct di_task tsk; + + /*channel state: use enum eDI_TOP_STATE */ + atomic_t ch_state[DI_CHANNEL_NUB]; + + bool in_flg[DI_CHANNEL_NUB]; + unsigned long mem_start[DI_CHANNEL_NUB]; + unsigned int mem_size[DI_CHANNEL_NUB]; + + bool sub_act_flg[DI_CHANNEL_NUB]; + /*struct mutex event_mutex[DI_CHANNEL_NUB];*/ + bool init_flg[DI_CHANNEL_NUB]; /*init_flag*/ + /*bool reg_flg[DI_CHANNEL_NUB];*/ /*reg_flag*/ + unsigned int reg_flg_ch; /*for x ch reg/unreg flg*/ + bool trig_unreg[DI_CHANNEL_NUB]; + bool hw_reg_flg; /*for di_reg_setting/di_unreg_setting*/ + bool act_flg ;/*active_flag*/ + + bool flg_hw_int; /*only once*/ + + struct di_mm_s mm; +}; + +/************************* + *debug register: + *************************/ +#define K_DI_SIZE_REG_LOG (1000) +#define K_DI_LAB_MOD (0xf001) +/*also see: dbg_mode_name*/ +enum eDI_DBG_MOD { + eDI_DBG_MOD_REGB, /* 0 */ + eDI_DBG_MOD_REGE, /* 1 */ + eDI_DBG_MOD_UNREGB, /* 2 */ + eDI_DBG_MOD_UNREGE, /* 3 */ + eDI_DBG_MOD_PRE_SETB, /* 4 */ + eDI_DBG_MOD_PRE_SETE, /* 5 */ + eDI_DBG_MOD_PRE_DONEB, /* 6 */ + eDI_DBG_MOD_PRE_DONEE, /* 7 */ + eDI_DBG_MOD_POST_SETB, /* 8 */ + eDI_DBG_MOD_POST_SETE, /* 9 */ + eDI_DBG_MOD_POST_IRQB, /* a */ + eDI_DBG_MOD_POST_IRQE, /* b */ + eDI_DBG_MOD_POST_DB, /* c */ + eDI_DBG_MOD_POST_DE, /* d */ + eDI_DBG_MOD_POST_CH_CHG, /* e */ + eDI_DBG_MOD_POST_TIMEOUT, /* F */ + + eDI_DBG_MOD_RVB, /*10 */ + eDI_DBG_MOD_RVE, /*11 */ + + eDI_DBG_MOD_POST_RESIZE, /*0x12 */ + eDI_DBG_MOD_END, + +}; + +enum eDI_LOG_TYPE { + eDI_LOG_TYPE_ALL = 1, + eDI_LOG_TYPE_REG, + eDI_LOG_TYPE_MOD, +}; + +struct di_dbg_reg { + unsigned int addr; + unsigned int val; + unsigned int st_bit:8, + b_w:8, + res:16; +}; + +struct di_dbg_mod { + unsigned int lable; /*0xf001: mean dbg mode*/ + unsigned int ch:8, + mod:8, + res:16; + unsigned int cnt;/*frame cnt*/ +}; + +union udbg_data { + struct di_dbg_reg reg; + struct di_dbg_mod mod; +}; + +struct di_dbg_reg_log { + bool en; + bool en_reg; + bool en_mod; + bool en_all; + bool en_notoverwrite; + + union udbg_data log[K_DI_SIZE_REG_LOG]; + unsigned int pos; + unsigned int wsize; + bool overflow; +}; + +struct di_dbg_data { + unsigned int vframe_type; /*use for type info*/ + unsigned int cur_channel; + struct di_dbg_reg_log reg_log; +}; + +struct di_data_l_s { + bool cfg_en[K_DI_CFG_NUB]; /*cfg_top*/ + int mp_uit[K_DI_MP_UIT_NUB]; /*eDI_MP_UI_T*/ + struct di_ch_s ch_data[DI_CHANNEL_NUB]; + int plane[DI_CHANNEL_NUB]; /*use for debugfs*/ + + struct di_dbg_data dbg_data; + struct di_mng_s mng; + struct di_hpre_s hw_pre; + struct di_hpst_s hw_pst; + struct dentry *dbg_root_top; /* dbg_fs*/ + /*pq_ops*/ + const struct pulldown_op_s *ops_pd; /* pulldown */ + const struct detect3d_op_s *ops_3d; /* detect_3d */ + const struct nr_op_s *ops_nr; /* nr */ + const struct mtn_op_s *ops_mtn; /* deinterlace_mtn */ + /*di ops for other module */ + /*struct di_ext_ops *di_api; */ + const struct di_meson_data *mdata; +}; + +/************************************** + * + * DEBUG infor + * + *************************************/ + +#define DBG_M_C_ALL 0x2000 /*all debug close*/ +#define DBG_M_O_ALL 0x1000 /*all debug open*/ + +#define DBG_M_DT 0x01 /*do table work*/ +#define DBG_M_REG 0x02 /*reg/unreg*/ +#define DBG_M_POST_REF 0x04 +#define DBG_M_TSK 0x08 +#define DBG_M_INIT 0x10 +#define DBG_M_EVENT 0x20 +#define DBG_M_FIRSTFRAME 0x40 +#define DBG_M_DBG 0x80 + +#define DBG_M_POLLING 0x100 +#define DBG_M_ONCE 0x200 + +extern unsigned int di_dbg; + +#define dbg_m(mark, fmt, args ...) \ + do { \ + if (di_dbg & DBG_M_C_ALL) \ + break; \ + if ((di_dbg & DBG_M_O_ALL) || \ + (di_dbg & (mark))) { \ + pr_info("dim:"fmt, ##args); \ + } \ + } while (0) + +#define PR_ERR(fmt, args ...) pr_err("dim:err:"fmt, ## args) +#define PR_WARN(fmt, args ...) pr_err("dim:warn:"fmt, ## args) +#define PR_INF(fmt, args ...) pr_info("dim:"fmt, ## args) + +#define dbg_dt(fmt, args ...) dbg_m(DBG_M_DT, fmt, ##args) +#define dbg_reg(fmt, args ...) dbg_m(DBG_M_REG, fmt, ##args) +#define dbg_post_ref(fmt, args ...) dbg_m(DBG_M_POST_REF, fmt, ##args) +#define dbg_poll(fmt, args ...) dbg_m(DBG_M_POLLING, fmt, ##args) +#define dbg_tsk(fmt, args ...) dbg_m(DBG_M_TSK, fmt, ##args) + +#define dbg_init(fmt, args ...) dbg_m(DBG_M_INIT, fmt, ##args) +#define dbg_ev(fmt, args ...) dbg_m(DBG_M_EVENT, fmt, ##args) +#define dbg_first_frame(fmt, args ...) dbg_m(DBG_M_FIRSTFRAME, fmt, ##args) +#define dbg_dbg(fmt, args ...) dbg_m(DBG_M_DBG, fmt, ##args) +#define dbg_once(fmt, args ...) dbg_m(DBG_M_ONCE, fmt, ##args) + +char *di_cfgx_get_name(enum eDI_CFGX_IDX idx); +bool di_cfgx_get(unsigned int ch, enum eDI_CFGX_IDX idx); +void di_cfgx_set(unsigned int ch, enum eDI_CFGX_IDX idx, bool en); + +static inline struct di_data_l_s *get_datal(void) +{ + return (struct di_data_l_s *)get_dim_de_devp()->data_l; +} + +static inline struct di_ch_s *get_chdata(unsigned int ch) +{ + return &get_datal()->ch_data[ch]; +} + +static inline struct di_mng_s *get_bufmng(void) +{ + return &get_datal()->mng; +} + +static inline unsigned long di_get_mem_start(unsigned int ch) +{ + return get_datal()->mng.mem_start[ch]; +} + +static inline void di_set_mem_info(unsigned int ch, + unsigned long mstart, unsigned int size) +{ + get_datal()->mng.mem_start[ch] = mstart; + get_datal()->mng.mem_size[ch] = size; +} + +static inline unsigned int *di_get_mem_size(unsigned int ch) +{ + return &get_datal()->mng.mem_size[ch]; +} + +static inline struct di_hpre_s *get_hw_pre(void) +{ + return &get_datal()->hw_pre; +} + +static inline struct di_hpst_s *get_hw_pst(void) +{ + return &get_datal()->hw_pst; +} + +/**************************************** + * flg_hw_int + * for hw set once + ****************************************/ +static inline bool di_get_flg_hw_int(void) +{ + return get_datal()->mng.flg_hw_int; +} + +static inline void di_set_flg_hw_int(bool on) +{ + get_datal()->mng.flg_hw_int = on; +} + +/********************** + * + * reg log: + *********************/ +static inline struct di_dbg_reg_log *get_dbg_reg_log(void) +{ + return &get_datal()->dbg_data.reg_log; +} + +/********************** + * + * flg_wait_int + *********************/ +static inline void di_pre_wait_irq_set(bool on) +{ + get_hw_pre()->flg_wait_int = on; +} + +static inline bool di_pre_wait_irq_get(void) +{ + return get_hw_pre()->flg_wait_int; +} + +static inline struct di_ores_s *get_orsc(unsigned int ch) +{ + return &get_datal()->ch_data[ch].rse_ori; +} + +static inline struct vframe_s **get_vframe_in(unsigned int ch) +{ + return &get_orsc(ch)->vframe_in[0]; +} + +static inline struct vframe_s *get_vframe_in_dup(unsigned int ch) +{ + return &get_orsc(ch)->vframe_in_dup[0]; +} + +static inline struct vframe_s *get_vframe_local(unsigned int ch) +{ + return &get_orsc(ch)->vframe_local[0]; +} + +static inline struct vframe_s *get_vframe_post(unsigned int ch) +{ + return &get_orsc(ch)->vframe_post[0]; +} + +static inline struct di_buf_s *get_buf_local(unsigned int ch) +{ + return &get_orsc(ch)->di_buf_local[0]; +} + +static inline struct di_buf_s *get_buf_in(unsigned int ch) +{ + return &get_orsc(ch)->di_buf_in[0]; +} + +static inline struct di_buf_s *get_buf_post(unsigned int ch) +{ + return &get_orsc(ch)->di_buf_post[0]; +} + +static inline struct queue_s *get_queue(unsigned int ch) +{ + return &get_orsc(ch)->queue[0]; +} + +static inline struct di_buf_pool_s *get_buf_pool(unsigned int ch) +{ + return &get_orsc(ch)->di_buf_pool[0]; +} + +static inline struct di_pre_stru_s *get_pre_stru(unsigned int ch) +{ + return &get_orsc(ch)->di_pre_stru; +} + +static inline struct di_post_stru_s *get_post_stru(unsigned int ch) +{ + return &get_orsc(ch)->di_post_stru; +} + +static inline enum eDI_SUB_ID get_current_channel(void) +{ + return get_datal()->dbg_data.cur_channel; +} + +static inline void set_current_channel(unsigned int channel) +{ + get_datal()->dbg_data.cur_channel = channel; +} + +static inline bool get_init_flag(unsigned char ch) +{ + return get_bufmng()->init_flg[ch]; +} + +static inline void set_init_flag(unsigned char ch, bool on) +{ + get_bufmng()->init_flg[ch] = on; +} + +extern const unsigned int di_ch2mask_table[DI_CHANNEL_MAX]; +/****************************************** + * + * reg / unreg + * + *****************************************/ +static inline bool get_reg_flag(unsigned char ch) +{ + unsigned int flg = get_bufmng()->reg_flg_ch; + bool ret = false; + + if (di_ch2mask_table[ch] & flg) + ret = true; + + /*dim_print("%s:%d\n", __func__, ret);*/ + return ret; +} + +static inline unsigned int get_reg_flag_all(void) +{ + return get_bufmng()->reg_flg_ch; +} + +static inline void set_reg_flag(unsigned char ch, bool on) +{ + unsigned int flg = get_bufmng()->reg_flg_ch; + + if (on) + get_bufmng()->reg_flg_ch = flg | di_ch2mask_table[ch]; + else + get_bufmng()->reg_flg_ch = flg & (~di_ch2mask_table[ch]); + /*dim_print("%s:%d\n", __func__, get_bufmng()->reg_flg_ch);*/ +} + +/****************************************** + * + * trig unreg: + * when unreg: set 1 + * when reg: set 0 + *****************************************/ + +static inline bool get_flag_trig_unreg(unsigned char ch) +{ + return get_bufmng()->trig_unreg[ch]; +} + +#if 0 +static inline unsigned int get_reg_flag_all(void) +{ + return get_bufmng()->reg_flg_ch; +} +#endif + +static inline void set_flag_trig_unreg(unsigned char ch, bool on) +{ + get_bufmng()->trig_unreg[ch] = on; +} + +static inline bool get_hw_reg_flg(void) +{ + return get_bufmng()->hw_reg_flg; +} + +static inline void set_hw_reg_flg(bool on) +{ + get_bufmng()->hw_reg_flg = on; +} + +static inline bool get_or_act_flag(void) +{ + return get_bufmng()->act_flg; +} + +static inline void set_or_act_flag(bool on) +{ + get_bufmng()->act_flg = on; +} + +/*sum*/ +static inline void di_sum_set_l(unsigned int ch, enum eDI_SUM id, + unsigned int val) +{ + get_chdata(ch)->sum[id] = val; +} + +static inline unsigned int di_sum_inc_l(unsigned int ch, enum eDI_SUM id) +{ + get_chdata(ch)->sum[id]++; + return get_chdata(ch)->sum[id]; +} + +static inline unsigned int di_sum_get_l(unsigned int ch, enum eDI_SUM id) +{ + return get_chdata(ch)->sum[id]; +} + +/*sum get and put*/ +static inline unsigned int get_sum_g(unsigned int ch) +{ + return get_datal()->ch_data[ch].sum_get; +} + +static inline void sum_g_inc(unsigned int ch) +{ + get_datal()->ch_data[ch].sum_get++; +} + +static inline void sum_g_clear(unsigned int ch) +{ + get_datal()->ch_data[ch].sum_get = 0; +} + +static inline unsigned int get_sum_p(unsigned int ch) +{ + return get_datal()->ch_data[ch].sum_put; +} + +static inline void sum_p_inc(unsigned int ch) +{ + get_datal()->ch_data[ch].sum_put++; +} + +static inline void sum_p_clear(unsigned int ch) +{ + get_datal()->ch_data[ch].sum_put = 0; +} + +/*bypass_state*/ +static inline bool di_bypass_state_get(unsigned int ch) +{ + return get_chdata(ch)->bypass_state; +} + +static inline void di_bypass_state_set(unsigned int ch, bool on) +{ + get_chdata(ch)->bypass_state = on; +} + +#if 0 +static inline struct semaphore *get_sema(void) +{ + return &get_dim_de_devp()->sema; +} +#endif + +static inline struct di_task *get_task(void) +{ + return &get_bufmng()->tsk; +} + +/****************************************** + * pq ops + *****************************************/ + +static inline const struct pulldown_op_s *get_ops_pd(void) +{ + return get_datal()->ops_pd; +} + +static inline const struct detect3d_op_s *get_ops_3d(void) +{ + return get_datal()->ops_3d; +} + +static inline const struct nr_op_s *get_ops_nr(void) +{ + return get_datal()->ops_nr; +} + +static inline const struct mtn_op_s *get_ops_mtn(void) +{ + return get_datal()->ops_mtn; +} + +#if 0 +static inline struct di_ext_ops *get_ops_api(void) +{ + return get_datal()->di_api; +} +#endif + +/****************************************** + * module para for di + *****************************************/ + +static inline int dimp_get(enum eDI_MP_UI_T idx) +{ + return get_datal()->mp_uit[idx]; +} + +static inline void dimp_set(enum eDI_MP_UI_T idx, int val) +{ + get_datal()->mp_uit[idx] = val; +} + +static inline int dimp_inc(enum eDI_MP_UI_T idx) +{ + get_datal()->mp_uit[idx]++; + return get_datal()->mp_uit[idx]; +} + +static inline int dimp_dec(enum eDI_MP_UI_T idx) +{ + get_datal()->mp_uit[idx]--; + return get_datal()->mp_uit[idx]; +} + +/****************************************** + * mm + *****************************************/ +static inline struct di_mm_s *dim_mm_get(void) +{ + return &get_datal()->mng.mm; +} + +/**/ +void di_tout_int(struct di_time_out_s *tout, unsigned int thd); +bool di_tout_contr(enum eDI_TOUT_CONTR cmd, struct di_time_out_s *tout); + +#endif /*__DI_DATA_L_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_dbg.c b/drivers/amlogic/media/di_multi/di_dbg.c new file mode 100644 index 0000000..9c7763b --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_dbg.c @@ -0,0 +1,1632 @@ +/* + * drivers/amlogic/media/di_multi/di_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 "di_data.h" +#include "di_dbg.h" + +#include "di_reg_tab.h" +#include "deinterlace.h" +#include "deinterlace_dbg.h" +#include "deinterlace_hw.h" +#include "di_data_l.h" +#include "di_que.h" +#include "di_task.h" +#include "di_prc.h" +#include "di_pre.h" +#include "di_post.h" + +/******************************** + *trace: + *******************************/ +#define CREATE_TRACE_POINTS +#include "dim_trace.h" + +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE dim_trace +#include + +/**********************/ +/* data get */ +static struct dentry **dich_get_dbgroot(unsigned int ch) +{ + return &get_datal()->ch_data[ch].dbg_rootx; +} + +static struct dentry **dich_get_dbgroot_top(void) +{ + return &get_datal()->dbg_root_top; +} + +static int *di_get_plane(void) +{ + return &get_datal()->plane[0]; +} + +static struct vframe_s *di_get_dbg_vframe_in(unsigned int ch) +{ + return &get_datal()->ch_data[ch].dbg_data.vfm_input; +} + +static struct vframe_s **di_get_dbg_vframe_out(unsigned int ch) +{ + return &get_datal()->ch_data[ch].dbg_data.pfm_out; +} + +/******************************** + *timer: + *******************************/ + +u64 cur_to_msecs(void) +{ + u64 cur = sched_clock(); + + do_div(cur, NSEC_PER_MSEC); + return cur; +} + +u64 cur_to_usecs(void)/*2019*/ +{ + u64 cur = sched_clock(); + + do_div(cur, NSEC_PER_USEC); + return cur; +} + +/******************************** + *trace: + *******************************/ + +static void trace_pre(unsigned int index, unsigned long ctime) +{ + trace_dim_pre("PRE-IRQ-0", index, ctime); +} + +static void trace_post(unsigned int index, unsigned long ctime) +{ + trace_dim_post("POST-IRQ-1", index, ctime); +} + +#define DI_TRACE_LIMIT 8 +static void trace_pre_get(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pre_getxx("PRE-GET-01", index, ustime); +} + +static void trace_pre_set(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pre_setxx("PRE-SET-01", index, ustime); +} + +static void trace_pre_ready(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pre_ready("PRE-READY2", index, ustime); +} + +static void trace_post_ready(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pst_ready("PST-READY3", index, ustime); +} + +static void trace_post_get(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pst_getxx("PST-GET-04", index, ustime); +} + +static void trace_post_get2(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pst_get2x("PST-GET-0a", index, ustime); +} + +static void trace_post_set(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pst_setxx("PST-SET-05", index, ustime); +} + +static void trace_post_irq(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pst_irxxx("PST-IRQ-06", index, ustime); +} + +static void trace_post_doing(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pst_doing("PST-DOI-07", index, ustime); +} + +static void trace_post_peek(unsigned int index) +{ + u64 ustime; + + if (di_get_disp_cnt() > DI_TRACE_LIMIT) + return; + + ustime = cur_to_usecs(); + trace_dim_pst_peekx("PST-PEEK-8", index, ustime); +} + +const struct dim_tr_ops_s dim_tr_ops = { + .pre = trace_pre, + .post = trace_post, + + .pre_get = trace_pre_get, + .pre_set = trace_pre_set, + .pre_ready = trace_pre_ready, + .post_ready = trace_post_ready, + .post_get = trace_post_get, + .post_get2 = trace_post_get2, + + .post_set = trace_post_set, + .post_ir = trace_post_irq, + .post_do = trace_post_doing, + .post_peek = trace_post_peek, +}; + +static unsigned int seq_get_channel(struct seq_file *s) +{ + int *pCh; + + pCh = (int *)s->private; + return *pCh; +} + +/******************************** + *debug register: + *******************************/ +/* also see enum eDI_DBG_MOD */ +const char * const dbg_mode_name[] = { + "REGB", + "REGE", + "UNREGB", + "UNREGE", + "PRE_SETB", + "PRE_SETE", + "PRE_DONEB", + "PRE_DONEE", + "PST_SETB", + "PST_SETE", + "PST_IRQB", + "PST_IRQE", + "PST_DB", + "PST_DE", + "PST_CH_CHG", + "PST_TOUT", + "RVB", + "RVE", + "PST_RESIZE", +}; + +const char *ddbg_get_mod_name(unsigned int mod) +{ + if (mod >= eDI_DBG_MOD_END) + return "nothing!"; + + return dbg_mode_name[mod]; +} + +void ddbg_reg_save(unsigned int addr, unsigned int val, + unsigned int st, unsigned int bw) +{ + struct di_dbg_reg dbg_reg; + struct di_dbg_reg_log *plog = get_dbg_reg_log(); + unsigned int pos; + + if (!plog->en_reg) + return; + if (plog->en_notoverwrite && plog->overflow) + return; + + pos = plog->pos; + + dbg_reg.addr = addr; + dbg_reg.val = val; + dbg_reg.st_bit = st; + dbg_reg.b_w = bw; + + plog->log[pos].reg = dbg_reg; + pos++; + if (pos >= (K_DI_SIZE_REG_LOG - 1)) { + if (plog->en_notoverwrite) { + plog->overflow = 1; + + } else { + pos = 0; + plog->overflow = 1; + } + } + plog->wsize++; + plog->pos = pos; +} + +void dim_ddbg_mod_save(unsigned int mod, unsigned int ch, unsigned int cnt) +{ + struct di_dbg_mod dbg_mod; + struct di_dbg_reg_log *plog = get_dbg_reg_log(); + unsigned int pos; +#if 1 +/*--------------------------*/ + if (ch) + h_dbg_reg_set(mod | 0x80000000); + else + h_dbg_reg_set(mod); +/*--------------------------*/ +#endif + if (!plog->en_mod) + return; + if (plog->en_notoverwrite && plog->overflow) + return; + pos = plog->pos; + + dbg_mod.lable = K_DI_LAB_MOD; + dbg_mod.ch = ch; + dbg_mod.mod = mod; + dbg_mod.cnt = cnt; + + plog->log[pos].mod = dbg_mod; + pos++; + if (pos >= (K_DI_SIZE_REG_LOG - 1)) { + if (plog->en_notoverwrite) { + plog->overflow = 1; + + } else { + pos = 0; + plog->overflow = 1; + } + } + plog->wsize++; + plog->pos = pos; +} + +#if 0 +void ddbg_sw(bool on) +{ + struct di_dbg_reg_log *plog = get_dbg_reg_log(); + + plog->en = on; +} +#else + +void ddbg_sw(enum eDI_LOG_TYPE mode, bool on) +{ + struct di_dbg_reg_log *plog = get_dbg_reg_log(); + + switch (mode) { + case eDI_LOG_TYPE_ALL: + plog->en_all = on; + break; + case eDI_LOG_TYPE_REG: + plog->en_reg = on; + break; + case eDI_LOG_TYPE_MOD: + plog->en_mod = on; + break; + default: + PR_WARN("%s:mode overlow:%d\n", __func__, mode); + break; + } +} +#endif +void ddbg_reg_clear(void) +{ + struct di_dbg_reg_log *plog = get_dbg_reg_log(); + + memset(plog, 0, sizeof(struct di_dbg_reg_log)); + plog->en_notoverwrite = 1; +} + +static int ddbg_log_reg_show(struct seq_file *seq, void *v) +{ + struct di_dbg_reg_log *plog = get_dbg_reg_log(); + unsigned int pos; + int i; + + if (plog->overflow) + pos = K_DI_SIZE_REG_LOG; + else + pos = plog->pos; + + seq_printf(seq, "%s:pos=%d,overflow=%d, size=%d\n", + __func__, plog->pos, plog->overflow, plog->wsize); + + for (i = 0; i < pos; i++) { + if (plog->log[i].mod.lable == K_DI_LAB_MOD) { + seq_printf(seq, "%d,ch[%d]:cnt[%d]:%s\n", + i, + plog->log[i].mod.ch, + plog->log[i].mod.cnt, + ddbg_get_mod_name(plog->log[i].mod.mod)); + continue; + } + + seq_printf(seq, "\t0x%x,0x%x,%d,%d\n", + plog->log[i].reg.addr, + plog->log[i].reg.val, + plog->log[i].reg.st_bit, + plog->log[i].reg.b_w); + } + + return 0; +} + +static ssize_t ddbg_log_reg_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int item, val; + char buf[80]; + int ret; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i", &item, &val); + + switch (ret) { + case 2: + if (item == 0 && val == 0) { + /*help info:*/ + pr_info("help:\n"); + /*all:*/ + pr_info("\t1 0 : log all disable\n"); + pr_info("\t1 1 : log all enable\n"); + /*reg:*/ + pr_info("\t2 0 : log reg disable\n"); + pr_info("\t2 1 : log reg enable\n"); + /*mod:*/ + pr_info("\t3 0 : log mod disable\n"); + pr_info("\t3 1 : log mod enable\n"); + /*clean:*/ + pr_info("\t4 0 : clear\n"); + break; + } + switch (item) { + case 1: + case 2: + case 3: + pr_info("ddbg_sw: %d\n", val); + ddbg_sw(item, val); + break; + case 4: + pr_info("ddbg_reg_clear\n"); + ddbg_reg_clear(); + break; + }; + + break; + default: + pr_info("err:please enter: 0 x for help\n"); + return -EINVAL; + } + + return count; +} + +/**********************/ +static int seq_file_vframe(struct seq_file *seq, void *v, struct vframe_s *pVfm) +{ + if (!pVfm) { + seq_puts(seq, "war: dump vframe NULL\n"); + return 0; + } + seq_printf(seq, "%-15s:0x%p\n", "addr", pVfm); + seq_printf(seq, "%-15s:%d\n", "index", pVfm->index); + seq_printf(seq, "%-15s:%d\n", "index_disp", pVfm->index_disp); + seq_printf(seq, "%-15s:%d\n", "omx_index", pVfm->omx_index); + seq_printf(seq, "%-15s:0x%x\n", "type", pVfm->type); + seq_printf(seq, "%-15s:0x%x\n", "type_backup", pVfm->type_backup); + seq_printf(seq, "%-15s:0x%x\n", "type_original", pVfm->type_original); + seq_printf(seq, "%-15s:%d\n", "blend_mode", pVfm->blend_mode); + seq_printf(seq, "%-15s:%d\n", "duration", pVfm->duration); + seq_printf(seq, "%-15s:%d\n", "duration_pull", pVfm->duration_pulldown); + seq_printf(seq, "%-15s:%d\n", "pts", pVfm->pts); + + seq_printf(seq, "%-15s:%lld\n", "pts_us64", pVfm->pts_us64); + seq_printf(seq, "%-15s:%d\n", "next_vf_pts_valid", + pVfm->next_vf_pts_valid); + seq_printf(seq, "%-15s:%d\n", "next_vf_pts", pVfm->next_vf_pts); + seq_printf(seq, "%-15s:%d\n", "disp_pts", pVfm->disp_pts); + seq_printf(seq, "%-15s:%lld\n", "disp_pts_us64", pVfm->disp_pts_us64); + seq_printf(seq, "%-15s:%lld\n", "timestamp", pVfm->timestamp); + seq_printf(seq, "%-15s:%d\n", "flag", pVfm->flag); + seq_printf(seq, "%-15s:0x%x\n", "canvas0Addr", pVfm->canvas0Addr); + seq_printf(seq, "%-15s:0x%x\n", "canvas1Addr", pVfm->canvas1Addr); + seq_printf(seq, "%-15s:0x%x\n", "compHeadAddr", pVfm->compHeadAddr); + seq_printf(seq, "%-15s:0x%x\n", "compBodyAddr", pVfm->compBodyAddr); + seq_printf(seq, "%-15s:%d\n", "plane_num", pVfm->plane_num); + + seq_printf(seq, "%-15s:%d\n", "bufWidth", pVfm->bufWidth); + seq_printf(seq, "%-15s:%d\n", "width", pVfm->width); + seq_printf(seq, "%-15s:%d\n", "height", pVfm->height); + seq_printf(seq, "%-15s:%d\n", "compWidth", pVfm->compWidth); + seq_printf(seq, "%-15s:%d\n", "compHeight", pVfm->compHeight); + seq_printf(seq, "%-15s:%d\n", "ratio_control", pVfm->ratio_control); + seq_printf(seq, "%-15s:%d\n", "bitdepth", pVfm->bitdepth); + seq_printf(seq, "%-15s:%d\n", "signal_type", pVfm->signal_type); + + /* + * bit 29: present_flag + * bit 28-26: video_format + * "component", "PAL", "NTSC", "SECAM", + * "MAC", "unspecified" + * bit 25: range "limited", "full_range" + * bit 24: color_description_present_flag + * bit 23-16: color_primaries + * "unknown", "bt709", "undef", "bt601", + * "bt470m", "bt470bg", "smpte170m", "smpte240m", + * "film", "bt2020" + * bit 15-8: transfer_characteristic + * "unknown", "bt709", "undef", "bt601", + * "bt470m", "bt470bg", "smpte170m", "smpte240m", + * "linear", "log100", "log316", "iec61966-2-4", + * "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", + * "smpte-st-2084", "smpte-st-428" + * bit 7-0: matrix_coefficient + * "GBR", "bt709", "undef", "bt601", + * "fcc", "bt470bg", "smpte170m", "smpte240m", + * "YCgCo", "bt2020nc", "bt2020c" + */ + seq_printf(seq, "%-15s:0x%x\n", "orientation", pVfm->orientation); + seq_printf(seq, "%-15s:0x%x\n", "video_angle", pVfm->video_angle); + seq_printf(seq, "%-15s:0x%x\n", "source_type", pVfm->source_type); + + seq_printf(seq, "%-15s:0x%x\n", "phase", pVfm->phase); + seq_printf(seq, "%-15s:0x%x\n", "source_mode", pVfm->source_mode); + seq_printf(seq, "%-15s:0x%x\n", "sig_fmt", pVfm->sig_fmt); + seq_printf(seq, "%-15s:0x%x\n", "trans_fmt", pVfm->trans_fmt); + + seq_printf(seq, "%-15s:0x%x\n", "mode_3d_enable", + pVfm->mode_3d_enable); + + seq_printf(seq, "%-15s:0x%p\n", "early_process_fun", + pVfm->early_process_fun); + seq_printf(seq, "%-15s:0x%p\n", "process_fun", + pVfm->early_process_fun); + seq_printf(seq, "%-15s:0x%p\n", "private_data", + pVfm->early_process_fun); + +#if 1 + /* vframe properties */ + +#endif + + /* pixel aspect ratio */ + seq_printf(seq, "%-15s:%d\n", "pixel_ratio", pVfm->pixel_ratio); + + /* ready from decode on jiffies_64 */ + seq_printf(seq, "%-15s:%d\n", "use_cnt", atomic_read(&pVfm->use_cnt)); + seq_printf(seq, "%-15s:%d\n", "frame_dirty", pVfm->frame_dirty); + /* + *prog_proc_config: + *1: process p from decoder as filed + *0: process p from decoder as frame + */ + seq_printf(seq, "%-15s:0x%x\n", "prog_proc_config", + pVfm->prog_proc_config); + /* used for indicate current video is motion or static */ + seq_printf(seq, "%-15s:%d\n", "combing_cur_lev", + pVfm->combing_cur_lev); + return 0; +} + +/**********************/ +/* debug input vframe */ +/**********************/ +void didbg_vframe_in_copy(unsigned int ch, struct vframe_s *pvfm) +{ + struct vframe_s *pvfm_t; + + if (!di_cfgx_get(ch, eDI_DBG_CFGX_IDX_VFM_IN)) + return; + + pvfm_t = di_get_dbg_vframe_in(ch); + + memcpy(pvfm_t, pvfm, sizeof(struct vframe_s)); +} + +static int seq_file_vframe_in_show(struct seq_file *seq, void *v) +{ + unsigned int ch; + + ch = seq_get_channel(seq); + seq_printf(seq, "%s:ch[%d]\n", __func__, ch); + + if (!di_cfgx_get(ch, eDI_DBG_CFGX_IDX_VFM_IN)) { + seq_puts(seq, "war: cfg[eDI_DBG_CFGX_IDX_VFM_IN] disable\n"); + return 0; + } + + seq_file_vframe(seq, v, di_get_dbg_vframe_in(ch)); + + return 0; +} + +/***********************/ +/* debug output vframe */ +/***********************/ +void didbg_vframe_out_save(struct vframe_s *pvfm) +{ + unsigned int ch; + struct vframe_s **pvfm_t; + + ch = DI_SUB_ID_S0; + if (!di_cfgx_get(ch, eDI_DBG_CFGX_IDX_VFM_OT)) + return; + + pvfm_t = di_get_dbg_vframe_out(ch); + *pvfm_t = pvfm; +} + +static int seq_file_vframe_out_show(struct seq_file *seq, void *v) +{ + unsigned int ch; + + ch = seq_get_channel(seq); + seq_printf(seq, "%s:ch[%d]\n", __func__, ch); + + if (!di_cfgx_get(ch, eDI_DBG_CFGX_IDX_VFM_OT)) { + seq_puts(seq, "war: cfg[eDI_DBG_CFGX_IDX_VFM_OT] disable\n"); + return 0; + } + + seq_file_vframe(seq, v, *di_get_dbg_vframe_out(ch)); + + return 0; +} + +/**********************/ +/* debug vframe type */ +/**********************/ +const struct di_vframe_type_info di_vtype_info[] = { + {"interlace", VIDTYPE_INTERLACE, NULL}, + {"bottom", VIDTYPE_INTERLACE_BOTTOM, NULL}, + + {"interllace first", VIDTYPE_INTERLACE_FIRST, NULL}, + {"mvc", VIDTYPE_MVC, NULL}, + {"no video en", VIDTYPE_NO_VIDEO_ENABLE, NULL}, + {"v422", VIDTYPE_VIU_422, NULL}, + {"field", VIDTYPE_VIU_FIELD, NULL}, + + {"single plane", VIDTYPE_VIU_SINGLE_PLANE, NULL}, + {"v444", VIDTYPE_VIU_444, NULL}, + {"nv21", VIDTYPE_VIU_NV21, NULL}, + {"vscale disable", VIDTYPE_VSCALE_DISABLE, NULL}, + {"cvs toggle", VIDTYPE_CANVAS_TOGGLE, NULL}, + {"pre interlace", VIDTYPE_PRE_INTERLACE, NULL}, + {"high run", VIDTYPE_HIGHRUN, NULL}, + {"compress", VIDTYPE_COMPRESS, NULL}, + {"pic", VIDTYPE_PIC, NULL}, + {"scatter", VIDTYPE_SCATTER, NULL}, + {"vd2", VIDTYPE_VD2, NULL}, + {"compress loss", VIDTYPE_COMPRESS_LOSS, NULL}, + {"comb", VIDTYPE_COMB_MODE, NULL}, + {"tb detect", TB_DETECT_MASK, NULL}, + + /*finish*/ + {NULL, TABLE_FLG_END, NULL}, +}; + +static void didbg_vtype_set(unsigned int type) +{ + get_datal()->dbg_data.vframe_type = type; +} + +static unsigned int didbg_vtype_get(void) +{ + return get_datal()->dbg_data.vframe_type; +} + +static int seq_file_vtype_show(struct seq_file *seq, void *v) +{ + unsigned int vtype; + int i; + unsigned int mask; + + i = 0; + vtype = didbg_vtype_get(); + + seq_printf(seq, "%s:vtype[0x%x]\n", __func__, vtype); + + while (di_vtype_info[i].name) { + mask = di_vtype_info[i].mask; + + if ((vtype & mask) == mask) { + seq_printf(seq, "\t%-15s:y\n", di_vtype_info[i].name); + } else { + if (di_vtype_info[i].other) { + seq_printf(seq, "\t%-15s:yes\n", + di_vtype_info[i].other); + } else { + seq_printf(seq, "\t%-15s:no\n", + di_vtype_info[i].name); + } + } + i++; + } + + return 0; +} + +ssize_t seq_file_vtype_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[20]; + int ret; + + unsigned int vtype; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + /*reg, bit, width, val*/ + #if 1 + ret = kstrtouint(buf, 0, &vtype); + if (ret) { + pr_info("war:please enter vtype\n"); + return 0; + } + pr_info("save type:0x%x", vtype); + didbg_vtype_set(vtype); + #else + + ret = sscanfxxx(buf, "%x", &vtype); + + /*--------------------------*/ + + switch (ret) { + case 1: + pr_info("save type:0x%x", vtype); + didbg_vtype_set(vtype); + break; + default: + pr_info("war:please enter vtype\n"); + break; + } + #endif + return count; +} + +/************************************** + * + * show vframe current + * + **************************************/ +static int seq_file_curr_vframe_show(struct seq_file *seq, void *v) +{ + unsigned int ch; + struct di_buf_s *p = NULL; + struct vframe_s *pvfm; + char *splt = "---------------------------"; + char *splt2 = "-------------"; + int itmp; + unsigned int tmpa[MAX_FIFO_SIZE]; + unsigned int psize; + + ch = seq_get_channel(seq); + seq_printf(seq, "%s:ch[%d]\n", __func__, ch); + + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* post_doing_list */ + /********************************/ + seq_puts(seq, "vfm for: post_doing_list:\n"); + queue_for_each_entry(p, ch, QUEUE_POST_DOING, list) { + pvfm = p->vframe; + seq_file_vframe(seq, v, pvfm); + seq_printf(seq, "%s\n", splt2); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* pre_ready_list */ + /********************************/ + seq_puts(seq, "pre_ready_list:\n"); + di_que_list(ch, QUE_PRE_READY, &tmpa[0], &psize); + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(ch, tmpa[itmp]); + + pvfm = p->vframe; + seq_file_vframe(seq, v, pvfm); + seq_printf(seq, "%s\n", splt2); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* post_ready_list */ + /********************************/ + di_que_list(ch, QUE_POST_READY, &tmpa[0], &psize); + seq_printf(seq, "post_ready_list: curr(%d)\n", psize); + + for (itmp = 0; itmp < psize; itmp++) { + p = pw_qindex_2_buf(ch, tmpa[itmp]); + pvfm = p->vframe; + seq_file_vframe(seq, v, pvfm); + seq_printf(seq, "%s\n", splt2); + } + seq_printf(seq, "%s\n", splt); + + /********************************/ + /* display_list */ + /********************************/ + seq_puts(seq, "display_list:\n"); + queue_for_each_entry(p, ch, QUEUE_DISPLAY, list) { + pvfm = p->vframe; + seq_file_vframe(seq, v, pvfm); + seq_printf(seq, "%s\n", splt2); + } + seq_printf(seq, "%s\n", splt); + + return 0; +} + +/************************************** + * + * summmary variable + * + **************************************/ +static int seq_file_sum_show(struct seq_file *seq, void *v) +{ + unsigned int ch; + char *sname; + unsigned int val; + unsigned int tsize; + int i; + + ch = seq_get_channel(seq); + + tsize = di_sum_get_tab_size();/*ARRAY_SIZE(di_sum_tab);*/ + + seq_printf(seq, "%s:ch[%d]\n", __func__, ch); + for (i = 0; i < tsize; i++) { + if (!di_sum_check(ch, i)) + continue; + di_sum_get_info(ch, i, &sname, &val); + seq_printf(seq, "\t%-2d:%-15s:%d\n", i, sname, val); + } + + seq_printf(seq, "%s:finish\n", __func__); + + return 0; +} + +/********************************/ +/* state */ +/********************************/ + +static int seq_file_state_show(struct seq_file *seq, void *v) +{ + unsigned int ch; + + ch = seq_get_channel(seq); + seq_printf(seq, "%s:ch[%d]\n", __func__, ch); + + dim_state_show(seq, v, ch); + + return 0; +} + +static int seq_file_mif_show(struct seq_file *seq, void *v) +{ + unsigned int ch; + + ch = seq_get_channel(seq); + seq_printf(seq, "%s:ch[%d]\n", __func__, ch); + + dim_dump_mif_size_state_show(seq, v, ch); + + return 0; +} + +/********************************/ +#define DEFINE_SEQ_SHOW_ONLY(__name) \ +static int __name ## _open(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, __name ## _show, inode->i_private); \ +} \ + \ +static const struct file_operations __name ## _fops = { \ + .owner = THIS_MODULE, \ + .open = __name ## _open, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ +} + +/*--------------------------*/ +#if 1 +/*note: this define can't used for x*/ +#define DEFINE_SEQ_SHOW_STORE(__name) \ +static int __name ## _open(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, __name ## _show, inode->i_private); \ +} \ + \ +static const struct file_operations __name ## _fops = { \ + .owner = THIS_MODULE, \ + .open = __name ## _open, \ + .read = seq_read, \ + .write = __name ## _store, \ + .llseek = seq_lseek, \ + .release = single_release, \ +} +#endif +/*--------------------------*/ +#define DEFINE_SHOW_STORE(__name) \ +static const struct file_operations __name ## _fops = { \ + .owner = THIS_MODULE, \ + .open = simple_open, \ + .read = __name ## _show, \ + .write = __name ## _store, \ +} + +/*--------------------------*/ +#define DEFINE_STORE_ONLY(__name) \ +static const struct file_operations __name ## _fops = { \ + .owner = THIS_MODULE, \ + .open = simple_open, \ + .read = NULL, \ + .write = __name ## _store, \ +} + +/**********************/ + +static int rcfgx_show(struct seq_file *s, void *what) +{ + int i; + int *pCh; + + pCh = (int *)s->private; + + seq_printf(s, "%s:ch[%d]\n", __func__, *pCh); + + for (i = eDI_CFGX_BEGIN; i < eDI_DBG_CFGX_END; i++) { + seq_printf(s, "\tidx[%2d]:%-15s:%d\n", i, + di_cfgx_get_name(i), + di_cfgx_get(*pCh, i)); + } + + return 0; +} + +/*************************************************************/ +static ssize_t wcfgx_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int item, val; + char buf[80]; + int ret; + int *pCh; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i", &item, &val); + + pCh = (int *)file->private_data; + pr_info("%s:ch[%d]\n", __func__, *pCh); + + switch (ret) { + case 2: + if ((item <= eDI_CFGX_BEGIN) || + (item >= eDI_DBG_CFGX_END)) { + pr_info("war:cfg_item is overflow[%d,%d]:%d\n", + eDI_CFGX_BEGIN, + eDI_DBG_CFGX_END, + item); + break; + } + if (val > 1) + pr_info("war:cfg value[%d] is not bool\n", val); + + pr_info("change cfg:%s\n", di_cfgx_get_name(item)); + pr_info("\t%d -> %d\n", di_cfgx_get(*pCh, item), val); + di_cfgx_set(*pCh, item, val); + break; + default: + pr_info("err:please enter: cfg_item, value(bool)\n"); + return -EINVAL; + } + + return count; +} + +/*************************************************************** + * parameter show and store for top : DI + **************************************************************/ +static int mpr_di_show(struct seq_file *s, void *what) +{ + int i; + + seq_printf(s, "%s:\n", __func__); + + for (i = eDI_MP_SUB_DI_B; i < eDI_MP_SUB_DI_E; i++) { + seq_printf(s, "\tidx[%2d]:%-15s:%d\n", + i - eDI_MP_SUB_DI_B, + di_mp_uit_get_name(i), + di_mp_uit_get(i)); + } + + return 0; +} + +static ssize_t mpw_di_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int item, rid; + char buf[80]; + int ret, val; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i", &item, &val); + + pr_info("%s:\n", __func__); + + switch (ret) { + case 2: + /*check []*/ + if (item >= (eDI_MP_SUB_DI_E - eDI_MP_SUB_DI_B)) { + PR_WARN("index is overflow[%d,%d]:%d\n", + 0, + eDI_MP_SUB_DI_E - eDI_MP_SUB_DI_B, + item); + break; + } + rid = item + eDI_MP_SUB_DI_B; + pr_info("change mp :%s\n", + di_mp_uit_get_name(rid)); + pr_info("\t%d -> %d\n", di_mp_uit_get(rid), val); + di_mp_uit_set(rid, val); + break; + default: + PR_ERR("please enter: id, value(int)\n"); + return -EINVAL; + } + + return count; +} + +/*************************************************************** + * parameter show and store for top : nr + **************************************************************/ +static int mpr_nr_show(struct seq_file *s, void *what) +{ + int i; + + seq_printf(s, "%s:\n", __func__); + + for (i = eDI_MP_SUB_NR_B; i < eDI_MP_SUB_NR_E; i++) { + seq_printf(s, "\tidx[%2d]:%-15s:%d\n", + i - eDI_MP_SUB_NR_B, + di_mp_uit_get_name(i), + di_mp_uit_get(i)); + } + + return 0; +} + +static ssize_t mpw_nr_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int item, rid; + char buf[80]; + int ret, val; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i", &item, &val); + + pr_info("%s:\n", __func__); + + switch (ret) { + case 2: + /*check []*/ + if (item >= (eDI_MP_SUB_NR_E - eDI_MP_SUB_NR_B)) { + PR_WARN("index is overflow[%d,%d]:%d\n", + 0, + eDI_MP_SUB_NR_E - eDI_MP_SUB_NR_B, + item); + break; + } + rid = item + eDI_MP_SUB_NR_B; + pr_info("change mp:%s\n", + di_mp_uit_get_name(rid)); + pr_info("\t%d -> %d\n", di_mp_uit_get(rid), val); + di_mp_uit_set(rid, val); + break; + default: + PR_ERR("please enter: id, value(int)\n"); + return -EINVAL; + } + + return count; +} + +/*************************************************************** + * parameter show and store for top : pulldown + **************************************************************/ +static int mpr_pd_show(struct seq_file *s, void *what) +{ + int i; + + seq_printf(s, "%s:\n", __func__); + + for (i = eDI_MP_SUB_PD_B; i < eDI_MP_SUB_PD_E; i++) { + seq_printf(s, "\tidx[%2d]:%-15s:%d\n", + i - eDI_MP_SUB_PD_B, + di_mp_uit_get_name(i), + di_mp_uit_get(i)); + } + + return 0; +} + +static ssize_t mpw_pd_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int item, rid; + char buf[80]; + int ret, val; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i", &item, &val); + + pr_info("%s:\n", __func__); + + switch (ret) { + case 2: + /*check []*/ + if (item >= (eDI_MP_SUB_PD_E - eDI_MP_SUB_PD_B)) { + PR_WARN("index is overflow[%d,%d]:%d\n", + 0, + eDI_MP_SUB_PD_E - eDI_MP_SUB_PD_B, + item); + break; + } + rid = item + eDI_MP_SUB_PD_B; + pr_info("change mp:%s\n", + di_mp_uit_get_name(rid)); + pr_info("\t%d -> %d\n", di_mp_uit_get(rid), val); + di_mp_uit_set(rid, val); + break; + default: + PR_ERR("please enter: id, value(int)\n"); + return -EINVAL; + } + + return count; +} + +/*************************************************************** + * parameter show and store for top : mtn + **************************************************************/ +static int mpr_mtn_show(struct seq_file *s, void *what) +{ + int i; + + seq_printf(s, "%s:\n", __func__); + + for (i = eDI_MP_SUB_MTN_B; i < eDI_MP_SUB_MTN_E; i++) { + seq_printf(s, "\tidx[%2d]:%-15s:%d\n", + i - eDI_MP_SUB_MTN_B, + di_mp_uit_get_name(i), + di_mp_uit_get(i)); + } + + return 0; +} + +static ssize_t mpw_mtn_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int item, rid; + char buf[80]; + int ret, val; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i", &item, &val); + + pr_info("%s:\n", __func__); + + switch (ret) { + case 2: + /*check []*/ + if (item >= (eDI_MP_SUB_MTN_E - eDI_MP_SUB_MTN_B)) { + PR_WARN("index is overflow[%d,%d]:%d\n", + 0, + eDI_MP_SUB_MTN_E - eDI_MP_SUB_MTN_B, + item); + break; + } + rid = item + eDI_MP_SUB_MTN_B; + pr_info("change mp:%s\n", + di_mp_uit_get_name(rid)); + pr_info("\t%d -> %d\n", di_mp_uit_get(rid), val); + di_mp_uit_set(rid, val); + break; + default: + PR_ERR("please enter: id, value(int)\n"); + return -EINVAL; + } + + return count; +} + +/**********************/ +static int mpxr_show(struct seq_file *s, void *what) +{ + int i; + int *pCh; + + pCh = (int *)s->private; + + seq_printf(s, "%s:ch[%d]\n", __func__, *pCh); + + for (i = eDI_MP_UIX_BEGIN; i < eDI_MP_UIX_END; i++) { + seq_printf(s, "\tidx[%2d]:%-15s:%d\n", i, + di_mp_uix_get_name(i), + di_mp_uix_get(*pCh, i)); + } + + return 0; +} + +/*************************************************************/ +static ssize_t mpxw_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int item, val; + char buf[80]; + int ret; + int *pCh; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i", &item, &val); + + pCh = (int *)file->private_data; + pr_info("%s:ch[%d]\n", __func__, *pCh); + + switch (ret) { + case 2: + if ((item <= eDI_MP_UIX_BEGIN) || + (item >= eDI_MP_UIX_END)) { + PR_WARN("mpxw is overflow[%d,%d]:%d\n", + eDI_MP_UIX_BEGIN, + eDI_MP_UIX_END, + item); + break; + } + + pr_info("change mp ch[%d]:%s\n", *pCh, + di_mp_uix_get_name(item)); + pr_info("\t%d -> %d\n", di_mp_uix_get(*pCh, item), val); + di_mp_uix_set(*pCh, item, val); + break; + default: + PR_ERR("please enter: mpxw, value(unsigned int)\n"); + return -EINVAL; + } + + return count; +} + +static ssize_t buf_cnt_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + int w, h, pflg, mc; + char buf[80]; + int ret, cnt_flg; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %i %i %i", &w, &h, &pflg, &mc); + + pr_info("%s:\n", __func__); + cnt_flg = 0; + switch (ret) { + case 2: + cnt_flg = 1; + pflg = 0; + mc = 1; + break; + case 3: + cnt_flg = 1; + mc = 1; + break; + case 4: + cnt_flg = 1; + break; + default: + PR_ERR("please enter: w, h, pflg, mc\n"); + return -EINVAL; + } + + if (cnt_flg) + di_cnt_buf(w, h, pflg, mc, 1, 1); + return count; +} + +/**********************/ +void dbg_f_post_disable(unsigned int para) +{ + dimh_disable_post_deinterlace_2(); +} + +void dbg_f_trig_task(unsigned int para) +{ + task_send_ready(); +} + +const struct di_dbg_func_s di_func_tab[] = { + {eDI_DBG_F_00, dbg_f_post_disable, + "dimh_disable_post_deinterlace_2", "no para"}, + {eDI_DBG_F_01, dbg_f_trig_task, + "trig task", "no para"}, + {eDI_DBG_F_02, dpre_dbg_f_trig, + "trig pre flow debug", "bit[4]:ddebug on/off;bi[3:0]:cnt"}, + {eDI_DBG_F_03, dpst_dbg_f_trig, + "trig post flow debug", "bit[4]:ddebug on/off;bi[3:0]:cnt"}, + {eDI_DBG_F_04, hpst_dbg_power_ctr_trig, + "trig post power", "1: on; 0: off"}, + + {eDI_DBG_F_05, hpst_dbg_mem_pd_trig, + "trig post mem pd", "no para"}, + {eDI_DBG_F_06, hpst_dbg_trig_gate, + "trig post gate off/on", "no para"}, + {eDI_DBG_F_07, hpst_dbg_trig_mif, + "trig post mif off/free", "no para"}, +}; + +static ssize_t wfunc_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int findex, para; + char buf[20]; + int ret; + + int i; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%i %x", &findex, ¶); + + switch (ret) { + case 2: + pr_info("func:%d,para=0x%x\n", findex, para); + for (i = 0; i < ARRAY_SIZE(di_func_tab); i++) { + if (i == findex && di_func_tab[i].index == findex) { + if (di_func_tab[i].func) + di_func_tab[i].func(para); + pr_info("func:%s finish\n", + di_func_tab[i].name); + break; + } + } + break; + default: + pr_info("warn: please enter function index and para\n"); + return -EINVAL; + } + + return count; +} + +static int rfunc_show(struct seq_file *seq, void *v) +{ + int i; + + seq_puts(seq, "debug function list:\n"); + + for (i = 0; i < ARRAY_SIZE(di_func_tab); i++) { + if (di_func_tab[i].index != i) + seq_printf(seq, "warn: index(%d->%d) is not map\n", + i, di_func_tab[i].index); + seq_printf(seq, "index[%d]:%s:%s\n", + di_func_tab[i].index, + di_func_tab[i].name, + di_func_tab[i].info); + } + return 0; +} + +/**********************/ +static ssize_t reg_show(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) +{ + char buf[80]; + + ssize_t len; + int *pInt; + + pInt = (int *)file->private_data; + pr_info("pInt=0x%p,val=%d\n", pInt, *pInt); + + len = snprintf(buf, sizeof(buf), "%s\n", + __func__); + + return simple_read_from_buffer(userbuf, count, ppos, buf, len); +} + +static ssize_t reg_store(struct file *file, const char __user *userbuf, + size_t count, loff_t *ppos) +{ + unsigned int reg, val; + char buf[80]; + int ret; + int *pInt; + + count = min_t(size_t, count, (sizeof(buf) - 1)); + if (copy_from_user(buf, userbuf, count)) + return -EFAULT; + + buf[count] = 0; + + ret = sscanf(buf, "%x %i", ®, &val); + + switch (ret) { + case 1: + pr_info("reg:0x%x\n", reg); + + pInt = (int *)file->private_data; + pr_info("pInt=0x%p,val=%d\n", pInt, *pInt); + break; + case 2: + pr_info("reg:0x%x,val=%d\n", reg, val); + break; + default: + return -EINVAL; + } + + return count; +} + +/**********************/ +DEFINE_SEQ_SHOW_ONLY(dim_reg_cue_int); +/**********************/ +DEFINE_SEQ_SHOW_ONLY(rcfgx); +DEFINE_SEQ_SHOW_ONLY(seq_file_vframe_in); +DEFINE_SEQ_SHOW_ONLY(seq_file_vframe_out); +DEFINE_SEQ_SHOW_ONLY(seq_file_state); +DEFINE_SEQ_SHOW_ONLY(seq_file_mif); +DEFINE_SEQ_SHOW_ONLY(seq_file_sum); + +DEFINE_SEQ_SHOW_ONLY(reg_con); +DEFINE_SEQ_SHOW_ONLY(rfunc); +DEFINE_SEQ_SHOW_ONLY(mpxr); +DEFINE_SEQ_SHOW_ONLY(mpr_di); +DEFINE_SEQ_SHOW_ONLY(mpr_nr); +DEFINE_SEQ_SHOW_ONLY(mpr_pd); +DEFINE_SEQ_SHOW_ONLY(mpr_mtn); + +DEFINE_SEQ_SHOW_ONLY(seq_file_curr_vframe); + +DEFINE_STORE_ONLY(wcfgx); +DEFINE_STORE_ONLY(wfunc); +DEFINE_STORE_ONLY(mpxw); +DEFINE_STORE_ONLY(mpw_di); +DEFINE_STORE_ONLY(mpw_nr); +DEFINE_STORE_ONLY(mpw_pd); +DEFINE_STORE_ONLY(mpw_mtn); +DEFINE_STORE_ONLY(buf_cnt); + +DEFINE_SHOW_STORE(reg); + +DEFINE_SEQ_SHOW_STORE(seq_file_vtype); +DEFINE_SEQ_SHOW_STORE(ddbg_log_reg); + +/**********************/ + +struct di_dbgfs_files_t { + const char *name; + const umode_t mode; + const struct file_operations *fops; +}; + +static const struct di_dbgfs_files_t di_debugfs_files_top[] = { + {"vtype", S_IFREG | 0644, &seq_file_vtype_fops}, + {"reg_log", S_IFREG | 0644, &ddbg_log_reg_fops}, + {"regctr", S_IFREG | 0644, ®_con_fops}, + {"rfunc", S_IFREG | 0644, &rfunc_fops}, + {"wfunc", S_IFREG | 0644, &wfunc_fops}, + {"reg_cue", S_IFREG | 0644, &dim_reg_cue_int_fops}, + /*module parameter*/ + {"mr_di", S_IFREG | 0644, &mpr_di_fops}, + {"mw_di", S_IFREG | 0644, &mpw_di_fops}, + {"mr_nr", S_IFREG | 0644, &mpr_nr_fops}, + {"mw_nr", S_IFREG | 0644, &mpw_nr_fops}, + {"mr_pd", S_IFREG | 0644, &mpr_pd_fops}, + {"mw_pd", S_IFREG | 0644, &mpw_pd_fops}, + {"mr_mtn", S_IFREG | 0644, &mpr_mtn_fops}, + {"mw_mtn", S_IFREG | 0644, &mpw_mtn_fops}, + {"buf_cnt", S_IFREG | 0644, &buf_cnt_fops}, +}; + +static const struct di_dbgfs_files_t di_debugfs_files[] = { + {"rcfgx", S_IFREG | 0644, &rcfgx_fops}, + {"wcfgx", S_IFREG | 0644, &wcfgx_fops}, + {"rvfm_in", S_IFREG | 0644, &seq_file_vframe_in_fops}, + {"rvfm_out", S_IFREG | 0644, &seq_file_vframe_out_fops}, + {"state", S_IFREG | 0644, &seq_file_state_fops}, + {"dumpmif", S_IFREG | 0644, &seq_file_mif_fops}, + {"test_reg", S_IFREG | 0644, ®_fops}, + {"sum", S_IFREG | 0644, &seq_file_sum_fops}, + {"mpxr", S_IFREG | 0644, &mpxr_fops}, + {"mpxw", S_IFREG | 0644, &mpxw_fops}, + {"vfmc", S_IFREG | 0644, &seq_file_curr_vframe_fops}, +}; + +void didbg_fs_init(void) +{ + int i, j; + char name[5]; + /*char buf[3];*/ + + struct dentry **root_ent; + + struct dentry *ent; + int *pPlane = di_get_plane(); + + for (i = 0; i < DI_CHANNEL_NUB; i++) { +#if 0 + strcpy(name, "di"); + sprintf(buf, "%01d", i); + strncat(name, buf, sizeof(buf) - 1); +#endif + snprintf(name, sizeof(name), "di%01d", i); + root_ent = dich_get_dbgroot(i); + *root_ent = debugfs_create_dir(name, NULL); + + *(pPlane + i) = i; + /*printk("plane 0x%p\n", &plane_ch[i]);*/ + for (j = 0; j < ARRAY_SIZE(di_debugfs_files); j++) { + ent = debugfs_create_file(di_debugfs_files[j].name, + di_debugfs_files[j].mode, + *root_ent, (pPlane + i), + di_debugfs_files[j].fops); + if (!ent) + PR_ERR("debugfs create failed\n"); + } + } + /*top*/ + root_ent = dich_get_dbgroot_top(); + *root_ent = debugfs_create_dir("di_top", NULL); + for (i = 0; i < ARRAY_SIZE(di_debugfs_files_top); i++) { + ent = debugfs_create_file(di_debugfs_files_top[i].name, + di_debugfs_files_top[i].mode, + *root_ent, NULL, + di_debugfs_files_top[i].fops); + if (!ent) + PR_ERR("debugfs top [%d]create failed\n", i); + } +} + +void didbg_fs_exit(void) +{ + struct dentry **root_ent; + int i; + + for (i = 0; i < DI_CHANNEL_NUB; i++) { + root_ent = dich_get_dbgroot(i); + debugfs_remove_recursive(*root_ent); + } + + /*top*/ + root_ent = dich_get_dbgroot_top(); + debugfs_remove_recursive(*root_ent); + + pr_info("%s:finish\n", __func__); +} + +/*-----------------------*/ + diff --git a/drivers/amlogic/media/di_multi/di_dbg.h b/drivers/amlogic/media/di_multi/di_dbg.h new file mode 100644 index 0000000..6636f5a --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_dbg.h @@ -0,0 +1,69 @@ +/* + * drivers/amlogic/media/di_multi/di_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. + * + */ + +#ifndef __DI_DBG_H__ +#define __DI_DBG_H__ + +#include +#include +#include + +void didbg_fs_init(void); +void didbg_fs_exit(void); + +void di_cfgx_init_val(void); + +void didbg_vframe_in_copy(unsigned int ch, struct vframe_s *pvfm); +void didbg_vframe_out_save(struct vframe_s *pvfm); + +/******************************** + *debug register: + *******************************/ +void ddbg_reg_save(unsigned int addr, unsigned int val, + unsigned int st, unsigned int bw); +void dim_ddbg_mod_save(unsigned int mod, + unsigned int ch, + unsigned int cnt); +void ddbg_sw(unsigned int mode, bool on); + +/******************************** + *time: + *******************************/ +u64 cur_to_msecs(void); +u64 cur_to_usecs(void); /*2019*/ + +/******************************** + *trace: + *******************************/ +struct dim_tr_ops_s { + void (*pre)(unsigned int index, unsigned long ctime); + void (*post)(unsigned int index, unsigned long ctime); + void (*pre_get)(unsigned int index); + void (*pre_set)(unsigned int index); + void (*pre_ready)(unsigned int index); + void (*post_ready)(unsigned int index); + void (*post_get)(unsigned int index); + void (*post_get2)(unsigned int index); + void (*post_set)(unsigned int index); + void (*post_ir)(unsigned int index); + void (*post_do)(unsigned int index); + void (*post_peek)(unsigned int index); +}; + +extern const struct dim_tr_ops_s dim_tr_ops; + +#endif /*__DI_DBG_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_post.c b/drivers/amlogic/media/di_multi/di_post.c new file mode 100644 index 0000000..3451d2d1 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_post.c @@ -0,0 +1,389 @@ +/* + * drivers/amlogic/media/di_multi/di_post.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 "deinterlace.h" +#include "deinterlace_dbg.h" + +#include "di_data_l.h" +#include "di_data.h" +#include "di_dbg.h" +#include "di_vframe.h" +#include "di_que.h" +#include "di_task.h" + +#include "di_prc.h" +#include "di_post.h" + +#include "nr_downscale.h" +#include "register.h" + +void dpost_clear(void)/*not been called*/ +{ + struct di_hpst_s *pst = get_hw_pst(); + + memset(pst, 0, sizeof(struct di_hpst_s)); +} + +void dpost_init(void) +{/*reg:*/ + struct di_hpst_s *pst = get_hw_pst(); + + pst->state = eDI_PST_ST_IDLE; + + /*timer out*/ + di_tout_int(&pst->tout, 40); /*ms*/ +} + +void pw_use_hw_post(enum eDI_SUB_ID channel, bool on) +{ + struct di_hpst_s *post = get_hw_pst(); + + post->hw_flg_busy_post = on; + if (on) + post->curr_ch = channel; +} + +static bool pw_try_sw_ch_next_post(enum eDI_SUB_ID channel) +{ + bool ret = false; + + struct di_hpst_s *post = get_hw_pst(); + enum eDI_SUB_ID lst_ch, nch; + + lst_ch = channel; + + nch = pw_ch_next_count(lst_ch); + if (!get_reg_flag(nch) || get_flag_trig_unreg(nch)) + return false; + + if (nch != channel) + dim_ddbg_mod_save(eDI_DBG_MOD_POST_CH_CHG, nch, 0);/*dbg*/ + + post->curr_ch = nch; + post->hw_flg_busy_post = true; + ret = true; + + /*dim_print("%s:%d->%d:%d\n", __func__, lst_ch, nch, ret);*/ + return ret; +} + +/*****************************/ +/* debug */ +/*****************************/ + +/*****************************/ +/* STEP */ +/*****************************/ + +bool dpst_step_idle(void) +{ + struct di_hpst_s *pst = get_hw_pst(); + bool reflesh = false; + + if (!pw_try_sw_ch_next_post(pst->curr_ch)) + return false; + + pst->pres = get_pre_stru(pst->curr_ch); + pst->psts = get_post_stru(pst->curr_ch); + pst->state++;/*tmp*/ + reflesh = true; + + return reflesh; +} + +bool dpst_step_check(void) +{ + struct di_hpst_s *pst = get_hw_pst(); + unsigned int ch; + struct di_post_stru_s *ppost; + bool reflesh = false; + + ch = pst->curr_ch; + ppost = get_post_stru(ch); + + if (queue_empty(ch, QUEUE_POST_DOING)) { + ppost->post_peek_underflow++; + pst->state--; + return reflesh; + } + + pst->state++; + reflesh = true; + + return reflesh; +} + +bool dpst_step_set(void) +{ + struct di_buf_s *di_buf = NULL; + vframe_t *vf_p = NULL; + struct di_post_stru_s *ppost; + struct di_hpst_s *pst = get_hw_pst(); + unsigned int ch; + bool reflesh = false; + ulong flags = 0; + + ch = pst->curr_ch; + ppost = get_post_stru(ch); + + di_buf = get_di_buf_head(ch, QUEUE_POST_DOING); + if (dim_check_di_buf(di_buf, 20, ch)) { + PR_ERR("%s:err1\n", __func__); + return reflesh; + } + + vf_p = di_buf->vframe; + if (ppost->run_early_proc_fun_flag) { + if (vf_p->early_process_fun) + vf_p->early_process_fun = dim_do_post_wr_fun; + } + + dim_print("%s:pr_index=%d\n", __func__, di_buf->process_fun_index); + if (di_buf->process_fun_index) { /*not bypass?*/ + + ppost->post_wr_cnt++; + spin_lock_irqsave(&plist_lock, flags); + dim_post_process(di_buf, 0, vf_p->width - 1, + 0, vf_p->height - 1, vf_p); + spin_unlock_irqrestore(&plist_lock, flags); + + /*begin to count timer*/ + di_tout_contr(eDI_TOUT_CONTR_EN, &pst->tout); + + ppost->post_de_busy = 1; + ppost->irq_time = cur_to_msecs(); + + /*state*/ + pst->state++; + /*reflesh = true;*/ + } else { + ppost->de_post_process_done = 1; /*trig done*/ + pst->flg_int_done = 1; + + /*state*/ + pst->state++;/*pst->state = eDI_PST_ST_DONE;*/ + reflesh = true; + } + ppost->cur_post_buf = di_buf; + + return reflesh; +} + +bool dpst_step_wait_int(void) +{ + struct di_hpst_s *pst = get_hw_pst(); + unsigned int ch; + struct di_post_stru_s *ppost; + bool reflesh = false; + ulong flags = 0; + + ch = pst->curr_ch; + + dim_print("%s:ch[%d],done_flg[%d]\n", __func__, + pst->curr_ch, pst->flg_int_done); + if (pst->flg_int_done) { + /*finish to count timer*/ + di_tout_contr(eDI_TOUT_CONTR_FINISH, &pst->tout); + spin_lock_irqsave(&plist_lock, flags); + dim_post_de_done_buf_config(ch); + spin_unlock_irqrestore(&plist_lock, flags); + pst->flg_int_done = false; + /*state*/ + pst->state = eDI_PST_ST_IDLE; + reflesh = true; + } else { + /*check if timeout:*/ + if (di_tout_contr(eDI_TOUT_CONTR_CHECK, &pst->tout)) { + ppost = get_post_stru(ch); + PR_WARN("ch[%d]:post timeout[%d]\n", ch, + ppost->cur_post_buf->seq); + dim_ddbg_mod_save(eDI_DBG_MOD_POST_TIMEOUT, ch, 0); + /*state*/ + pst->state = eDI_PST_ST_TIMEOUT; + reflesh = true; + } + } + return reflesh; +} + +void dpst_timeout(unsigned int ch) +{ + hpst_dbg_mem_pd_trig(0); + post_close_new(); + #if 0 + di_post_set_flow(1, eDI_POST_FLOW_STEP1_STOP); + di_post_reset(); + #endif + dimh_pst_trig_resize(); +} + +bool dpst_step_timeout(void) +{ + struct di_hpst_s *pst = get_hw_pst(); + unsigned int ch; + bool reflesh = false; + ulong flags = 0; + + ch = pst->curr_ch; + dpst_timeout(ch); + spin_lock_irqsave(&plist_lock, flags); + dim_post_de_done_buf_config(ch); + spin_unlock_irqrestore(&plist_lock, flags); + pst->flg_int_done = false; + + /*state*/ + pst->state = eDI_PST_ST_IDLE; + reflesh = true; + + return reflesh; +} + +bool dpst_step_done(void)/*this step no use ?*/ +{ + struct di_hpst_s *pst = get_hw_pst(); + unsigned int ch; + bool reflesh = false; + + ch = pst->curr_ch; +/* dim_post_de_done_buf_config(ch);*/ + + /*state*/ + pst->state = eDI_PST_ST_IDLE; + reflesh = true; + + return reflesh; +} + +const struct di_func_tab_s di_pst_func_tab[] = { + {eDI_PST_ST_EXIT, NULL}, + {eDI_PST_ST_IDLE, dpst_step_idle}, + {eDI_PST_ST_CHECK, dpst_step_check}, + {eDI_PST_ST_SET, dpst_step_set}, + {eDI_PST_ST_WAIT_INT, dpst_step_wait_int}, + {eDI_PST_ST_TIMEOUT, dpst_step_timeout}, + {eDI_PST_ST_DONE, dpst_step_done}, +}; + +const char * const dpst_state_name[] = { + "EXIT", + "IDLE", /*swith to next channel?*/ + "CHECK", + "SET", + "WAIT_INT", + "TIMEOUT", + "DONE", +}; + +const char *dpst_state_name_get(enum eDI_PST_ST state) +{ + if (state > eDI_PST_ST_DONE) + return "nothing"; + + return dpst_state_name[state]; +} + +bool dpst_can_exit(unsigned int ch) +{ + struct di_hpst_s *pst = get_hw_pst(); + bool ret = false; + + if (ch != pst->curr_ch) { + ret = true; + } else { + if (pst->state <= eDI_PST_ST_IDLE) + ret = true; + } + pr_info("%s:ch[%d]:curr[%d]:stat[%s] ret[%d]\n", + __func__, + ch, pst->curr_ch, + dpst_state_name_get(pst->state), + ret); + return ret; +} + +static bool dpst_process_step2(void) +{ + struct di_hpst_s *pst = get_hw_pst(); + enum eDI_PST_ST pst_st = pst->state; + unsigned int ch; + + ch = pst->curr_ch; + if (pst_st > eDI_PST_ST_EXIT) + dim_recycle_post_back(ch); + + if ((pst_st <= eDI_PST_ST_DONE) && + di_pst_func_tab[pst_st].func) + return di_pst_func_tab[pst_st].func(); + else + return false; +} + +void dpst_dbg_f_trig(unsigned int cmd) +{ + struct di_task *tsk = get_task(); + + struct di_hpst_s *pst = get_hw_pst(); + + if (down_interruptible(&tsk->sem)) { + PR_ERR("%s:can't get sem\n", __func__); + return; + } + + /*set on/off and trig*/ + if (cmd & 0x10) { + pst->dbg_f_en = 1; + pst->dbg_f_cnt = cmd & 0xf; + pst->dbg_f_lstate = pst->state; + } else { + pst->dbg_f_en = 0; + } + + up(&tsk->sem); +} + +void dpst_process(void) +{ + bool reflesh; + + struct di_hpst_s *pst = get_hw_pst(); + + if (pst->dbg_f_en) { + if (pst->dbg_f_cnt) { + dpst_process_step2(); + pst->dbg_f_cnt--; + } + if (pst->dbg_f_lstate != pst->state) { + pr_info("ch[%d]:state:%s->%s\n", + pst->curr_ch, + dpst_state_name_get(pst->dbg_f_lstate), + dpst_state_name_get(pst->state)); + + pst->dbg_f_lstate = pst->state; + } + return; + } + + reflesh = true; + + while (reflesh) + reflesh = dpst_process_step2(); +} diff --git a/drivers/amlogic/media/di_multi/di_post.h b/drivers/amlogic/media/di_multi/di_post.h new file mode 100644 index 0000000..1b4d88d --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_post.h @@ -0,0 +1,27 @@ +/* + * drivers/amlogic/media/di_multi/di_post.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_POST_H__ +#define __DI_POST_H__ + +void dpost_init(void); +void dpst_process(void); +const char *dpst_state_name_get(enum eDI_PST_ST state); +void dpst_dbg_f_trig(unsigned int cmd); +bool dpst_can_exit(unsigned int ch); + +#endif /*__DI_POST_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_pps.c b/drivers/amlogic/media/di_multi/di_pps.c new file mode 100644 index 0000000..4f20941 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_pps.c @@ -0,0 +1,628 @@ +/* + * drivers/amlogic/media/di_multi/di_pps.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 "di_pps.h" +#include "register.h" + +#include + +#if 0 +/* pps filter coefficients */ +#define COEF_BICUBIC 0 +#define COEF_3POINT_TRIANGLE 1 +#define COEF_4POINT_TRIANGLE 2 +#define COEF_BILINEAR 3 +#define COEF_2POINT_BILINEAR 4 +#define COEF_BICUBIC_SHARP 5 +#define COEF_3POINT_TRIANGLE_SHARP 6 +#define COEF_3POINT_BSPLINE 7 +#define COEF_4POINT_BSPLINE 8 +#define COEF_3D_FILTER 9 +#define COEF_NULL 0xff +#define TOTAL_FILTERS 10 + +#define MAX_NONLINEAR_FACTOR 0x40 + +const u32 vpp_filter_coefs_bicubic_sharp[] = { + 3, + 33 | 0x8000, + /* 0x01f80090, 0x01f80100, 0xff7f0200, 0xfe7f0300, */ + 0x01fa008c, 0x01fa0100, 0xff7f0200, 0xfe7f0300, + 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900, + 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff, + 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, + 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd, + 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb, + 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, + 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9, + 0xf84848f8 +}; + +const u32 vpp_filter_coefs_bicubic[] = { + 4, + 33, + 0x00800000, 0x007f0100, 0xff7f0200, 0xfe7f0300, + 0xfd7e0500, 0xfc7e0600, 0xfb7d0800, 0xfb7c0900, + 0xfa7b0b00, 0xfa7a0dff, 0xf9790fff, 0xf97711ff, + 0xf87613ff, 0xf87416fe, 0xf87218fe, 0xf8701afe, + 0xf76f1dfd, 0xf76d1ffd, 0xf76b21fd, 0xf76824fd, + 0xf76627fc, 0xf76429fc, 0xf7612cfc, 0xf75f2ffb, + 0xf75d31fb, 0xf75a34fb, 0xf75837fa, 0xf7553afa, + 0xf8523cfa, 0xf8503ff9, 0xf84d42f9, 0xf84a45f9, + 0xf84848f8 +}; + +const u32 vpp_filter_coefs_bilinear[] = { + 4, + 33, + 0x00800000, 0x007e0200, 0x007c0400, 0x007a0600, + 0x00780800, 0x00760a00, 0x00740c00, 0x00720e00, + 0x00701000, 0x006e1200, 0x006c1400, 0x006a1600, + 0x00681800, 0x00661a00, 0x00641c00, 0x00621e00, + 0x00602000, 0x005e2200, 0x005c2400, 0x005a2600, + 0x00582800, 0x00562a00, 0x00542c00, 0x00522e00, + 0x00503000, 0x004e3200, 0x004c3400, 0x004a3600, + 0x00483800, 0x00463a00, 0x00443c00, 0x00423e00, + 0x00404000 +}; + +const u32 vpp_3d_filter_coefs_bilinear[] = { + 2, + 33, + 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, + 0x78080000, 0x760a0000, 0x740c0000, 0x720e0000, + 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000, + 0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, + 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000, + 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000, + 0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, + 0x48380000, 0x463a0000, 0x443c0000, 0x423e0000, + 0x40400000 +}; + +const u32 vpp_filter_coefs_3point_triangle[] = { + 3, + 33, + 0x40400000, 0x3f400100, 0x3d410200, 0x3c410300, + 0x3a420400, 0x39420500, 0x37430600, 0x36430700, + 0x35430800, 0x33450800, 0x32450900, 0x31450a00, + 0x30450b00, 0x2e460c00, 0x2d460d00, 0x2c470d00, + 0x2b470e00, 0x29480f00, 0x28481000, 0x27481100, + 0x26491100, 0x25491200, 0x24491300, 0x234a1300, + 0x224a1400, 0x214a1500, 0x204a1600, 0x1f4b1600, + 0x1e4b1700, 0x1d4b1800, 0x1c4c1800, 0x1b4c1900, + 0x1a4c1a00 +}; + +/* point_num =4, filt_len =4, group_num = 64, [1 2 1] */ +const u32 vpp_filter_coefs_4point_triangle[] = { + 4, + 33, + 0x20402000, 0x20402000, 0x1f3f2101, 0x1f3f2101, + 0x1e3e2202, 0x1e3e2202, 0x1d3d2303, 0x1d3d2303, + 0x1c3c2404, 0x1c3c2404, 0x1b3b2505, 0x1b3b2505, + 0x1a3a2606, 0x1a3a2606, 0x19392707, 0x19392707, + 0x18382808, 0x18382808, 0x17372909, 0x17372909, + 0x16362a0a, 0x16362a0a, 0x15352b0b, 0x15352b0b, + 0x14342c0c, 0x14342c0c, 0x13332d0d, 0x13332d0d, + 0x12322e0e, 0x12322e0e, 0x11312f0f, 0x11312f0f, + 0x10303010 +}; + +/* + *4th order (cubic) b-spline + *filt_cubic point_num =4, filt_len =4, group_num = 64, [1 5 1] + */ +const u32 vpp_filter_coefs_4point_bspline[] = { + 4, + 33, + 0x15561500, 0x14561600, 0x13561700, 0x12561800, + 0x11551a00, 0x11541b00, 0x10541c00, 0x0f541d00, + 0x0f531e00, 0x0e531f00, 0x0d522100, 0x0c522200, + 0x0b522300, 0x0b512400, 0x0a502600, 0x0a4f2700, + 0x094e2900, 0x084e2a00, 0x084d2b00, 0x074c2c01, + 0x074b2d01, 0x064a2f01, 0x06493001, 0x05483201, + 0x05473301, 0x05463401, 0x04453601, 0x04433702, + 0x04423802, 0x03413a02, 0x03403b02, 0x033f3c02, + 0x033d3d03 +}; + +/*3rd order (quadratic) b-spline*/ +/*filt_quadratic, point_num =3, filt_len =3, group_num = 64, [1 6 1] */ +const u32 vpp_filter_coefs_3point_bspline[] = { + 3, + 33, + 0x40400000, 0x3e420000, 0x3c440000, 0x3a460000, + 0x38480000, 0x364a0000, 0x344b0100, 0x334c0100, + 0x314e0100, 0x304f0100, 0x2e500200, 0x2c520200, + 0x2a540200, 0x29540300, 0x27560300, 0x26570300, + 0x24580400, 0x23590400, 0x215a0500, 0x205b0500, + 0x1e5c0600, 0x1d5c0700, 0x1c5d0700, 0x1a5e0800, + 0x195e0900, 0x185e0a00, 0x175f0a00, 0x15600b00, + 0x14600c00, 0x13600d00, 0x12600e00, 0x11600f00, + 0x10601000 +}; + +/*filt_triangle, point_num =3, filt_len =2.6, group_num = 64, [1 7 1] */ +const u32 vpp_filter_coefs_3point_triangle_sharp[] = { + 3, + 33, + 0x40400000, 0x3e420000, 0x3d430000, 0x3b450000, + 0x3a460000, 0x38480000, 0x37490000, 0x354b0000, + 0x344c0000, 0x324e0000, 0x314f0000, 0x2f510000, + 0x2e520000, 0x2c540000, 0x2b550000, 0x29570000, + 0x28580000, 0x265a0000, 0x245c0000, 0x235d0000, + 0x215f0000, 0x20600000, 0x1e620000, 0x1d620100, + 0x1b620300, 0x19630400, 0x17630600, 0x15640700, + 0x14640800, 0x12640a00, 0x11640b00, 0x0f650c00, + 0x0d660d00 +}; + +const u32 vpp_filter_coefs_2point_binilear[] = { + 2, + 33, + 0x80000000, 0x7e020000, 0x7c040000, 0x7a060000, + 0x78080000, 0x760a0000, 0x740c0000, 0x720e0000, + 0x70100000, 0x6e120000, 0x6c140000, 0x6a160000, + 0x68180000, 0x661a0000, 0x641c0000, 0x621e0000, + 0x60200000, 0x5e220000, 0x5c240000, 0x5a260000, + 0x58280000, 0x562a0000, 0x542c0000, 0x522e0000, + 0x50300000, 0x4e320000, 0x4c340000, 0x4a360000, + 0x48380000, 0x463a0000, 0x443c0000, 0x423e0000, + 0x40400000 +}; + +static const u32 *filter_table[] = { + vpp_filter_coefs_bicubic, + vpp_filter_coefs_3point_triangle, + vpp_filter_coefs_4point_triangle, + vpp_filter_coefs_bilinear, + vpp_filter_coefs_2point_binilear, + vpp_filter_coefs_bicubic_sharp, + vpp_filter_coefs_3point_triangle_sharp, + vpp_filter_coefs_3point_bspline, + vpp_filter_coefs_4point_bspline, + vpp_3d_filter_coefs_bilinear +}; + +static int chroma_filter_table[] = { + COEF_BICUBIC, /* bicubic */ + COEF_3POINT_TRIANGLE, + COEF_4POINT_TRIANGLE, + COEF_4POINT_TRIANGLE, /* bilinear */ + COEF_2POINT_BILINEAR, + COEF_3POINT_TRIANGLE, /* bicubic_sharp */ + COEF_3POINT_TRIANGLE, /* 3point_triangle_sharp */ + COEF_3POINT_TRIANGLE, /* 3point_bspline */ + COEF_4POINT_TRIANGLE, /* 4point_bspline */ + COEF_3D_FILTER /* can not change */ +}; + +static unsigned int vert_scaler_filter = 0xff; +module_param(vert_scaler_filter, uint, 0664); +MODULE_PARM_DESC(vert_scaler_filter, "vert_scaler_filter"); + +static unsigned int vert_chroma_scaler_filter = 0xff; +module_param(vert_chroma_scaler_filter, uint, 0664); +MODULE_PARM_DESC(vert_chroma_scaler_filter, "vert_chroma_scaler_filter"); + +static unsigned int horz_scaler_filter = 0xff; +module_param(horz_scaler_filter, uint, 0664); +MODULE_PARM_DESC(horz_scaler_filter, "horz_scaler_filter"); + +bool pre_scaler_en = true; +module_param(pre_scaler_en, bool, 0664); +MODULE_PARM_DESC(pre_scaler_en, "pre_scaler_en"); +#endif +/*bicubic*/ +static const unsigned int di_filt_coef0[] = { + 0x00800000, + 0x007f0100, + 0xff7f0200, + 0xfe7f0300, + 0xfd7e0500, + 0xfc7e0600, + 0xfb7d0800, + 0xfb7c0900, + 0xfa7b0b00, + 0xfa7a0dff, + 0xf9790fff, + 0xf97711ff, + 0xf87613ff, + 0xf87416fe, + 0xf87218fe, + 0xf8701afe, + 0xf76f1dfd, + 0xf76d1ffd, + 0xf76b21fd, + 0xf76824fd, + 0xf76627fc, + 0xf76429fc, + 0xf7612cfc, + 0xf75f2ffb, + 0xf75d31fb, + 0xf75a34fb, + 0xf75837fa, + 0xf7553afa, + 0xf8523cfa, + 0xf8503ff9, + 0xf84d42f9, + 0xf84a45f9, + 0xf84848f8 +}; + +/* 2 point bilinear */ +static const unsigned int di_filt_coef1[] = { + 0x00800000, + 0x007e0200, + 0x007c0400, + 0x007a0600, + 0x00780800, + 0x00760a00, + 0x00740c00, + 0x00720e00, + 0x00701000, + 0x006e1200, + 0x006c1400, + 0x006a1600, + 0x00681800, + 0x00661a00, + 0x00641c00, + 0x00621e00, + 0x00602000, + 0x005e2200, + 0x005c2400, + 0x005a2600, + 0x00582800, + 0x00562a00, + 0x00542c00, + 0x00522e00, + 0x00503000, + 0x004e3200, + 0x004c3400, + 0x004a3600, + 0x00483800, + 0x00463a00, + 0x00443c00, + 0x00423e00, + 0x00404000 +}; + +/* 2 point bilinear, bank_length == 2*/ +static const unsigned int di_filt_coef2[] = { + 0x80000000, + 0x7e020000, + 0x7c040000, + 0x7a060000, + 0x78080000, + 0x760a0000, + 0x740c0000, + 0x720e0000, + 0x70100000, + 0x6e120000, + 0x6c140000, + 0x6a160000, + 0x68180000, + 0x661a0000, + 0x641c0000, + 0x621e0000, + 0x60200000, + 0x5e220000, + 0x5c240000, + 0x5a260000, + 0x58280000, + 0x562a0000, + 0x542c0000, + 0x522e0000, + 0x50300000, + 0x4e320000, + 0x4c340000, + 0x4a360000, + 0x48380000, + 0x463a0000, + 0x443c0000, + 0x423e0000, + 0x40400000 +}; + +#define ZOOM_BITS 20 +#define PHASE_BITS 16 + +static enum f2v_vphase_type_e top_conv_type = F2V_P2P; +static enum f2v_vphase_type_e bot_conv_type = F2V_P2P; +static unsigned int prehsc_en; +static unsigned int prevsc_en; + +static const unsigned char f2v_420_in_pos_luma[F2V_TYPE_MAX] = { +0, 2, 0, 2, 0, 0, 0, 2, 0}; +#if 0 +static const unsigned char f2v_420_in_pos_chroma[F2V_TYPE_MAX] = { + 1, 5, 1, 5, 2, 2, 1, 5, 2}; +#endif +static const unsigned char f2v_420_out_pos[F2V_TYPE_MAX] = { +0, 2, 2, 0, 0, 2, 0, 0, 0}; + +static void f2v_get_vertical_phase(unsigned int zoom_ratio, + enum f2v_vphase_type_e type, + unsigned char bank_length, + struct pps_f2v_vphase_s *vphase) +{ + int offset_in, offset_out; + + /* luma */ + offset_in = f2v_420_in_pos_luma[type] << PHASE_BITS; + offset_out = (f2v_420_out_pos[type] * zoom_ratio) + >> (ZOOM_BITS - PHASE_BITS); + + vphase->rcv_num = bank_length; + if (bank_length == 4 || bank_length == 3) + vphase->rpt_num = 1; + else + vphase->rpt_num = 0; + + if (offset_in > offset_out) { + vphase->rpt_num = vphase->rpt_num + 1; + vphase->phase = + ((4 << PHASE_BITS) + offset_out - offset_in) >> 2; + } else { + while ((offset_in + (4 << PHASE_BITS)) <= offset_out) { + if (vphase->rpt_num == 1) + vphase->rpt_num = 0; + else + vphase->rcv_num++; + offset_in += 4 << PHASE_BITS; + } + vphase->phase = (offset_out - offset_in) >> 2; + } +} + +/* + * patch 1: inp scaler 0: di wr scaler + * support: TM2 + * not support: SM1 + */ +void dim_pps_config(unsigned char path, int src_w, int src_h, + int dst_w, int dst_h) +{ + struct pps_f2v_vphase_s vphase; + + int i; + int hsc_en = 0, vsc_en = 0; + int vsc_double_line_mode; + unsigned int p_src_w, p_src_h; + unsigned int vert_phase_step, horz_phase_step; + unsigned char top_rcv_num, bot_rcv_num; + unsigned char top_rpt_num, bot_rpt_num; + unsigned short top_vphase, bot_vphase; + unsigned char is_frame; + int vert_bank_length = 4; + + const unsigned int *filt_coef0 = di_filt_coef0; + /*unsigned int *filt_coef1 = di_filt_coef1;*/ + const unsigned int *filt_coef2 = di_filt_coef2; + + vsc_double_line_mode = 0; + + if (src_h != dst_h) + vsc_en = 1; + if (src_w != dst_w) + hsc_en = 1; + /* config hdr size */ + Wr_reg_bits(DI_HDR_IN_HSIZE, dst_w, 0, 13); + Wr_reg_bits(DI_HDR_IN_VSIZE, dst_h, 0, 13); + p_src_w = (prehsc_en ? ((src_w + 1) >> 1) : src_w); + p_src_h = prevsc_en ? ((src_h + 1) >> 1) : src_h; + + Wr(DI_SC_HOLD_LINE, 0x10); + + if (p_src_w > 2048) { + /*force vert bank length = 2*/ + vert_bank_length = 2; + vsc_double_line_mode = 1; + } + + /*write vert filter coefs*/ + Wr(DI_SC_COEF_IDX, 0x0000); + for (i = 0; i < 33; i++) { + if (vert_bank_length == 2) + Wr(DI_SC_COEF, filt_coef2[i]); /*bilinear*/ + else + Wr(DI_SC_COEF, filt_coef0[i]); /*bicubic*/ + } + + /*write horz filter coefs*/ + Wr(DI_SC_COEF_IDX, 0x0100); + for (i = 0; i < 33; i++) + Wr(DI_SC_COEF, filt_coef0[i]); /*bicubic*/ + + if (p_src_h > 2048) + vert_phase_step = ((p_src_h << 18) / dst_h) << 2; + else + vert_phase_step = (p_src_h << 20) / dst_h; + if (p_src_w > 2048) + horz_phase_step = ((p_src_w << 18) / dst_w) << 2; + else + horz_phase_step = (p_src_w << 20) / dst_w; + + is_frame = ((top_conv_type == F2V_IT2P) || + (top_conv_type == F2V_IB2P) || + (top_conv_type == F2V_P2P)); + + if (is_frame) { + f2v_get_vertical_phase(vert_phase_step, top_conv_type, + vert_bank_length, &vphase); + top_rcv_num = vphase.rcv_num; + top_rpt_num = vphase.rpt_num; + top_vphase = vphase.phase; + + bot_rcv_num = 0; + bot_rpt_num = 0; + bot_vphase = 0; + } else { + f2v_get_vertical_phase(vert_phase_step, top_conv_type, + vert_bank_length, &vphase); + top_rcv_num = vphase.rcv_num; + top_rpt_num = vphase.rpt_num; + top_vphase = vphase.phase; + + f2v_get_vertical_phase(vert_phase_step, bot_conv_type, + vert_bank_length, &vphase); + bot_rcv_num = vphase.rcv_num; + bot_rpt_num = vphase.rpt_num; + bot_vphase = vphase.phase; + } + vert_phase_step = (vert_phase_step << 4); + horz_phase_step = (horz_phase_step << 4); + + Wr(DI_SC_LINE_IN_LENGTH, src_w); + Wr(DI_SC_PIC_IN_HEIGHT, src_h); + Wr(DI_VSC_REGION12_STARTP, 0); + Wr(DI_VSC_REGION34_STARTP, ((dst_h << 16) | dst_h)); + Wr(DI_VSC_REGION4_ENDP, (dst_h - 1)); + + Wr(DI_VSC_START_PHASE_STEP, vert_phase_step); + Wr(DI_VSC_REGION0_PHASE_SLOPE, 0); + Wr(DI_VSC_REGION1_PHASE_SLOPE, 0); + Wr(DI_VSC_REGION3_PHASE_SLOPE, 0); + Wr(DI_VSC_REGION4_PHASE_SLOPE, 0); + + Wr(DI_VSC_PHASE_CTRL, + ((vsc_double_line_mode << 17) | + (!is_frame) << 16) | + (0 << 15) | + (bot_rpt_num << 13) | + (bot_rcv_num << 8) | + (0 << 7) | + (top_rpt_num << 5) | + (top_rcv_num)); + Wr(DI_VSC_INI_PHASE, (bot_vphase << 16) | top_vphase); + Wr(DI_HSC_REGION12_STARTP, 0); + Wr(DI_HSC_REGION34_STARTP, (dst_w << 16) | dst_w); + Wr(DI_HSC_REGION4_ENDP, dst_w - 1); + + Wr(DI_HSC_START_PHASE_STEP, horz_phase_step); + Wr(DI_HSC_REGION0_PHASE_SLOPE, 0); + Wr(DI_HSC_REGION1_PHASE_SLOPE, 0); + Wr(DI_HSC_REGION3_PHASE_SLOPE, 0); + Wr(DI_HSC_REGION4_PHASE_SLOPE, 0); + + Wr(DI_HSC_PHASE_CTRL, (1 << 21) | (4 << 16) | 0); + Wr_reg_bits(DI_SC_TOP_CTRL, (path ? 3 : 0), 29, 2); + Wr(DI_SC_MISC, + (prevsc_en << 21) | + (prehsc_en << 20) | /* prehsc_en */ + (prevsc_en << 19) | /* prevsc_en */ + (vsc_en << 18) | /* vsc_en */ + (hsc_en << 17) | /* hsc_en */ + ((vsc_en | hsc_en) << 16) | /* sc_top_en */ + (1 << 15) | /* vd1 sc out enable */ + (0 << 12) | /* horz nonlinear 4region enable */ + (4 << 8) | /* horz scaler bank length */ + (0 << 5) | /* vert scaler phase field enable */ + (0 << 4) | /* vert nonlinear 4region enable */ + (vert_bank_length << 0) /* vert scaler bank length */ + ); + + pr_info("[pps] %s input %d %d output %d %d.\n", + path ? "pre" : "post", src_w, src_h, dst_w, dst_h); +} + +/* + * 0x374e ~ 0x376d, 20 regs + */ +void dim_dump_pps_reg(unsigned int base_addr) +{ + unsigned int i = 0x374e; + + pr_info("-----dump pps start-----\n"); + for (i = 0x374e; i < 0x376e; i++) { + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), + i, dim_RDMA_RD(i)); + } + pr_info("-----dump pps end-----\n"); +} + +/* + * di pre h scaling down function + * only have h scaling down + * support: sm1 tm2 ... + * 0x37b0 ~ 0x37b5 + */ +void dim_inp_hsc_setting(u32 src_w, u32 dst_w) +{ + u32 i; + u32 hsc_en; + u32 horz_phase_step; + const int *filt_coef0 = di_filt_coef0; + /*int *filt_coef1 = di_filt_coef1;*/ + /*int *filt_coef2 = di_filt_coef2;*/ + + if (src_w == dst_w) { + hsc_en = 0; + } else { + hsc_en = 1; + /*write horz filter coefs*/ + dim_RDMA_WR(DI_VIU_HSC_COEF_IDX, 0x0100); + for (i = 0; i < 33; i++) /*bicubic*/ + dim_RDMA_WR(DI_VIU_HSC_COEF, filt_coef0[i]); + + horz_phase_step = (src_w << 20) / dst_w; + horz_phase_step = (horz_phase_step << 4); + dim_RDMA_WR(DI_VIU_HSC_WIDTHM1, + (src_w - 1) << 16 | (dst_w - 1)); + dim_RDMA_WR(DI_VIU_HSC_PHASE_STEP, horz_phase_step); + dim_RDMA_WR(DI_VIU_HSC_PHASE_CTRL, 0); + } + dim_RDMA_WR(DI_VIU_HSC_CTRL, + (4 << 20) | /* initial receive number*/ + (0 << 12) | /* initial pixel ptr*/ + (1 << 10) | /* repeat first pixel number*/ + (0 << 8) | /* sp422 mode*/ + (4 << 4) | /* horz scaler bank length*/ + (0 << 2) | /* phase0 always en*/ + (0 << 1) | /* nearest_en*/ + (hsc_en << 0)); /* hsc_en*/ +} + +/* + * 0x37b0 ~ 0x37b5 + */ +void dim_dump_hdownscler_reg(unsigned int base_addr) +{ + unsigned int i = 0x374e; + + pr_info("-----dump hdownscler start-----\n"); + for (i = 0x37b0; i < 0x37b5; i++) { + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), + i, dim_RDMA_RD(i)); + } + pr_info("-----dump hdownscler end-----\n"); +} + +int dim_seq_file_module_para_pps(struct seq_file *seq) +{ + seq_puts(seq, "pps---------------\n"); + + return 0; +} + diff --git a/drivers/amlogic/media/di_multi/di_pps.h b/drivers/amlogic/media/di_multi/di_pps.h new file mode 100644 index 0000000..334db9d --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_pps.h @@ -0,0 +1,112 @@ +/* + * drivers/amlogic/media/di_multi/di_pps.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_PPS_H +#define DI_PPS_H +#include +#include +#if 0 +#define VPP_FLAG_WIDEMODE_MASK 0x0000000F +#define VPP_FLAG_INTERLACE_OUT 0x00000010 +#define VPP_FLAG_INTERLACE_IN 0x00000020 +#define VPP_FLAG_CBCR_SEPARATE 0x00000040 +#define VPP_FLAG_ZOOM_SHORTSIDE 0x00000080 +#define VPP_FLAG_AR_MASK 0x0003ff00 +#define VPP_FLAG_AR_BITS 8 +#define VPP_FLAG_PORTRAIT_MODE 0x00040000 +#define VPP_FLAG_VSCALE_DISABLE 0x00080000 + +#define IDX_H (2 << 8) +#define IDX_V_Y (1 << 13) +#define IDX_V_CBCR ((1 << 13) | (1 << 8)) + +#define ASPECT_4_3 ((3 << 8) / 4) +#define ASPECT_16_9 ((9 << 8) / 16) + +#define SPEED_CHECK_DONE 0 +#define SPEED_CHECK_HSKIP 1 +#define SPEED_CHECK_VSKIP 2 + +enum f2v_vphase_type_e { + F2V_IT2IT = 0, + F2V_IB2IB, + F2V_IT2IB, + F2V_IB2IT, + F2V_P2IT, + F2V_P2IB, + F2V_IT2P, + F2V_IB2P, + F2V_P2P, + F2V_TYPE_MAX +}; /* frame to video conversion type */ +#endif + +enum hdr2_scaler_e { + hdr2_scaler_postdi = 0, + hdr2_scaler_predi = 1, +}; + +struct pps_f2v_vphase_s { + unsigned char rcv_num; + unsigned char rpt_num; + unsigned short phase; +}; + +struct ppsfilter_mode_s { + u32 pps_hf_start_phase_step; + u32 pps_hf_start_phase_slope; + u32 pps_hf_end_phase_slope; + const u32 *pps_vert_coeff; + const u32 *pps_horz_coeff; + u32 pps_sc_misc_; + u32 pps_vsc_start_phase_step; + u32 pps_hsc_start_phase_step; + bool pps_pre_vsc_en; + bool pps_pre_hsc_en; + u32 pps_vert_filter; + u32 pps_horz_filter; + const u32 *pps_chroma_coeff; + u32 pps_chroma_filter_en; +}; + +struct pps_frame_par_s { + u32 pps_vsc_startp; + u32 pps_vsc_endp; + u32 pps_hsc_startp; + u32 pps_hsc_linear_startp; + u32 pps_hsc_linear_endp; + u32 pps_hsc_endp; + u32 VPP_hf_ini_phase_; + struct f2v_vphase_s VPP_vf_ini_phase_[9]; + u32 pps_pic_in_height_; + u32 pps_line_in_length_; + struct ppsfilter_mode_s pps_filter; + u32 pps_3d_mode; + u32 trans_fmt; + /* bit[1:0] 0: 1 pic,1:two pic one buf,2:tow pic two buf */ + /* bit[2]0:select pic0,1:select pic1 */ + /* bit[3]0:pic0 first,1:pic1 first */ + bool pps_3d_scale; +}; + +void dim_pps_config(unsigned char path, int src_w, int src_h, + int dst_w, int dst_h); +void dim_dump_pps_reg(unsigned int base_addr); +void dim_inp_hsc_setting(u32 src_w, u32 dst_w); +void dim_dump_hdownscler_reg(unsigned int base_addr); + +#endif diff --git a/drivers/amlogic/media/di_multi/di_prc.c b/drivers/amlogic/media/di_multi/di_prc.c new file mode 100644 index 0000000..3a98e99 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_prc.c @@ -0,0 +1,1966 @@ +/* + * drivers/amlogic/media/di_multi/di_prc.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 "deinterlace.h" + +#include "di_data_l.h" +#include "di_data.h" +#include "di_dbg.h" +#include "di_vframe.h" +#include "di_que.h" +#include "di_task.h" + +#include "di_prc.h" +#include "di_pre.h" +#include "di_post.h" +#include "di_api.h" + +/************************************** + * + * cfg ctr top + * bool + **************************************/ + +const struct di_cfg_ctr_s di_cfg_top_ctr[K_DI_CFG_NUB] = { + /*same order with enum eDI_DBG_CFG*/ + /* cfg for top */ + [eDI_CFG_BEGIN] = {"cfg top begin ", eDI_CFG_BEGIN, 0}, + + [eDI_CFG_first_bypass] = {"first_bypass", + eDI_CFG_first_bypass, 1}, + [eDI_CFG_ref_2] = {"ref_2", + eDI_CFG_ref_2, 0}, + [eDI_CFG_END] = {"cfg top end ", eDI_CFG_END, 0}, + +}; + +char *di_cfg_top_get_name(enum eDI_CFG_TOP_IDX idx) +{ + return di_cfg_top_ctr[idx].name; +} + +void di_cfg_top_get_info(unsigned int idx, char **name) +{ + if (di_cfg_top_ctr[idx].id != idx) + PR_ERR("%s:err:idx not map [%d->%d]\n", __func__, + idx, di_cfg_top_ctr[idx].id); + + *name = di_cfg_top_ctr[idx].name; +} + +bool di_cfg_top_check(unsigned int idx) +{ + unsigned int tsize; + + tsize = ARRAY_SIZE(di_cfg_top_ctr); + if (idx >= tsize) { + PR_ERR("%s:err:overflow:%d->%d\n", + __func__, idx, tsize); + return false; + } + if (idx != di_cfg_top_ctr[idx].id) { + PR_ERR("%s:err:not map:%d->%d\n", + __func__, idx, di_cfg_top_ctr[idx].id); + return false; + } + pr_info("\t%-15s=%d\n", di_cfg_top_ctr[idx].name, + di_cfg_top_ctr[idx].default_val); + return true; +} + +void di_cfg_top_init_val(void) +{ + int i; + + pr_info("%s:\n", __func__); + for (i = eDI_CFG_BEGIN; i < eDI_CFG_END; i++) { + if (!di_cfg_top_check(i)) + continue; + di_cfg_top_set(i, di_cfg_top_ctr[i].default_val); + } + pr_info("%s:finish\n", __func__); +} + +bool di_cfg_top_get(enum eDI_CFG_TOP_IDX id) +{ + return get_datal()->cfg_en[id]; +} + +void di_cfg_top_set(enum eDI_CFG_TOP_IDX id, bool en) +{ + get_datal()->cfg_en[id] = en; +} + +/************************************** + * + * cfg ctr x + * bool + **************************************/ + +const struct di_cfgx_ctr_s di_cfgx_ctr[K_DI_CFGX_NUB] = { + /*same order with enum eDI_DBG_CFG*/ + + /* cfg channel x*/ + [eDI_CFGX_BEGIN] = {"cfg x begin ", eDI_CFGX_BEGIN, 0}, + /* bypass_all */ + [eDI_CFGX_BYPASS_ALL] = {"bypass_all", eDI_CFGX_BYPASS_ALL, 0}, + [eDI_CFGX_END] = {"cfg x end ", eDI_CFGX_END, 0}, + + /* debug cfg x */ + [eDI_DBG_CFGX_BEGIN] = {"cfg dbg begin ", eDI_DBG_CFGX_BEGIN, 0}, + [eDI_DBG_CFGX_IDX_VFM_IN] = {"vfm_in", eDI_DBG_CFGX_IDX_VFM_IN, 0}, + [eDI_DBG_CFGX_IDX_VFM_OT] = {"vfm_out", eDI_DBG_CFGX_IDX_VFM_OT, 1}, + [eDI_DBG_CFGX_END] = {"cfg dbg end", eDI_DBG_CFGX_END, 0}, +}; + +char *di_cfgx_get_name(enum eDI_CFGX_IDX idx) +{ + return di_cfgx_ctr[idx].name; +} + +void di_cfgx_get_info(enum eDI_CFGX_IDX idx, char **name) +{ + if (di_cfgx_ctr[idx].id != idx) + PR_ERR("%s:err:idx not map [%d->%d]\n", __func__, + idx, di_cfgx_ctr[idx].id); + + *name = di_cfgx_ctr[idx].name; +} + +bool di_cfgx_check(unsigned int idx) +{ + unsigned int tsize; + + tsize = ARRAY_SIZE(di_cfgx_ctr); + if (idx >= tsize) { + PR_ERR("%s:err:overflow:%d->%d\n", + __func__, idx, tsize); + return false; + } + if (idx != di_cfgx_ctr[idx].id) { + PR_ERR("%s:err:not map:%d->%d\n", + __func__, idx, di_cfgx_ctr[idx].id); + return false; + } + pr_info("\t%-15s=%d\n", di_cfgx_ctr[idx].name, + di_cfgx_ctr[idx].default_val); + return true; +} + +void di_cfgx_init_val(void) +{ + int i, ch; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + for (i = eDI_CFGX_BEGIN; i < eDI_DBG_CFGX_END; i++) + di_cfgx_set(ch, i, di_cfgx_ctr[i].default_val); + } +} + +bool di_cfgx_get(unsigned int ch, enum eDI_CFGX_IDX idx) +{ + return get_datal()->ch_data[ch].cfgx_en[idx]; +} + +void di_cfgx_set(unsigned int ch, enum eDI_CFGX_IDX idx, bool en) +{ + get_datal()->ch_data[ch].cfgx_en[idx] = en; +} + +/************************************** + * + * module para top + * int + **************************************/ + +const struct di_mp_uit_s di_mp_ui_top[] = { + /*same order with enum eDI_MP_UI*/ + /* for top */ + [eDI_MP_UI_T_BEGIN] = {"module para top begin ", + eDI_MP_UI_T_BEGIN, 0}, + /**************************************/ + [eDI_MP_SUB_DI_B] = {"di begin ", + eDI_MP_SUB_DI_B, 0}, + [eDI_MP_force_prog] = {"bool:force_prog:1", + eDI_MP_force_prog, 1}, + [eDI_MP_combing_fix_en] = {"bool:combing_fix_en,def:1", + eDI_MP_combing_fix_en, 1}, + [eDI_MP_cur_lev] = {"int cur_lev,def:2", + eDI_MP_cur_lev, 2}, + [eDI_MP_pps_dstw] = {"pps_dstw:int", + eDI_MP_pps_dstw, 0}, + [eDI_MP_pps_dsth] = {"pps_dsth:int", + eDI_MP_pps_dsth, 0}, + [eDI_MP_pps_en] = {"pps_en:bool", + eDI_MP_pps_en, 0}, + [eDI_MP_pps_position] = {"pps_position:uint:def:1", + eDI_MP_pps_position, 1}, + [eDI_MP_pre_enable_mask] = {"pre_enable_mask:bit0:ma;bit1:mc:def:3", + eDI_MP_pre_enable_mask, 3}, + [eDI_MP_post_refresh] = {"post_refresh:bool", + eDI_MP_post_refresh, 0}, + [eDI_MP_nrds_en] = {"nrds_en:bool", + eDI_MP_nrds_en, 0}, + [eDI_MP_bypass_3d] = {"bypass_3d:int:def:1", + eDI_MP_bypass_3d, 1}, + [eDI_MP_bypass_trick_mode] = {"bypass_trick_mode:int:def:1", + eDI_MP_bypass_trick_mode, 1}, + [eDI_MP_invert_top_bot] = {"invert_top_bot:int", + eDI_MP_invert_top_bot, 0}, + [eDI_MP_skip_top_bot] = {"skip_top_bot:int:", + /*1or2: may affect atv when bypass di*/ + eDI_MP_skip_top_bot, 0}, + [eDI_MP_force_width] = {"force_width:int", + eDI_MP_force_width, 0}, + [eDI_MP_force_height] = {"force_height:int", + eDI_MP_force_height, 0}, + [eDI_MP_prog_proc_config] = {"prog_proc_config:int:def:0x", +/* 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 + */ + eDI_MP_prog_proc_config, ((1 << 5) | (1 << 1) | 1)}, + [eDI_MP_start_frame_drop_count] = {"start_frame_drop_count:int:2", + eDI_MP_start_frame_drop_count, 2}, + [eDI_MP_same_field_top_count] = {"same_field_top_count:long?", + eDI_MP_same_field_top_count, 0}, + [eDI_MP_same_field_bot_count] = {"same_field_bot_count:long?", + eDI_MP_same_field_bot_count, 0}, + [eDI_MP_vpp_3d_mode] = {"vpp_3d_mode:int", + eDI_MP_vpp_3d_mode, 0}, + [eDI_MP_force_recovery_count] = {"force_recovery_count:uint", + eDI_MP_force_recovery_count, 0}, + [eDI_MP_pre_process_time] = {"pre_process_time:int", + eDI_MP_pre_process_time, 0}, + [eDI_MP_bypass_post] = {"bypass_post:int", + eDI_MP_bypass_post, 0}, + [eDI_MP_post_wr_en] = {"post_wr_en:bool:1", + eDI_MP_post_wr_en, 1}, + [eDI_MP_post_wr_support] = {"post_wr_support:uint", + eDI_MP_post_wr_support, 0}, + [eDI_MP_bypass_post_state] = {"bypass_post_state:int", +/* 0, use di_wr_buf still; + * 1, call dim_pre_de_done_buf_clear to clear di_wr_buf; + * 2, do nothing + */ + eDI_MP_bypass_post_state, 0}, + [eDI_MP_use_2_interlace_buff] = {"use_2_interlace_buff:int", + eDI_MP_use_2_interlace_buff, 0}, + [eDI_MP_debug_blend_mode] = {"debug_blend_mode:int:-1", + eDI_MP_debug_blend_mode, -1}, + [eDI_MP_nr10bit_support] = {"nr10bit_support:uint", + /* 0: not support nr10bit, 1: support nr10bit */ + eDI_MP_nr10bit_support, 0}, + [eDI_MP_di_stop_reg_flag] = {"di_stop_reg_flag:uint", + eDI_MP_di_stop_reg_flag, 0}, + [eDI_MP_mcpre_en] = {"mcpre_en:bool:true", + eDI_MP_mcpre_en, 1}, + [eDI_MP_check_start_drop_prog] = {"check_start_drop_prog:bool", + eDI_MP_check_start_drop_prog, 0}, + [eDI_MP_overturn] = {"overturn:bool:?", + eDI_MP_overturn, 0}, + [eDI_MP_full_422_pack] = {"full_422_pack:bool", + eDI_MP_full_422_pack, 0}, + [eDI_MP_cma_print] = {"cma_print:bool:1", + eDI_MP_cma_print, 0}, + [eDI_MP_pulldown_enable] = {"pulldown_enable:bool:1", + eDI_MP_pulldown_enable, 1}, + [eDI_MP_di_force_bit_mode] = {"di_force_bit_mode:uint:10", + eDI_MP_di_force_bit_mode, 10}, + [eDI_MP_calc_mcinfo_en] = {"calc_mcinfo_en:bool:1", + eDI_MP_calc_mcinfo_en, 1}, + [eDI_MP_colcfd_thr] = {"colcfd_thr:uint:128", + eDI_MP_colcfd_thr, 128}, + [eDI_MP_post_blend] = {"post_blend:uint", + eDI_MP_post_blend, 0}, + [eDI_MP_post_ei] = {"post_ei:uint", + eDI_MP_post_ei, 0}, + [eDI_MP_post_cnt] = {"post_cnt:uint", + eDI_MP_post_cnt, 0}, + [eDI_MP_di_log_flag] = {"di_log_flag:uint", + eDI_MP_di_log_flag, 0}, + [eDI_MP_di_debug_flag] = {"di_debug_flag:uint", + eDI_MP_di_debug_flag, 0}, + [eDI_MP_buf_state_log_threshold] = {"buf_state_log_threshold:unit:16", + eDI_MP_buf_state_log_threshold, 16}, + [eDI_MP_di_vscale_skip_enable] = {"di_vscale_skip_enable:int", +/* + * bit[2]: enable bypass all when skip + * bit[1:0]: enable bypass post when skip + */ + eDI_MP_di_vscale_skip_enable, 0}, + [eDI_MP_di_vscale_skip_count] = {"di_vscale_skip_count:int", + eDI_MP_di_vscale_skip_count, 0}, + [eDI_MP_di_vscale_skip_count_real] = {"di_vscale_skip_count_real:int", + eDI_MP_di_vscale_skip_count_real, 0}, + [eDI_MP_det3d_en] = {"det3d_en:bool", + eDI_MP_det3d_en, 0}, + [eDI_MP_post_hold_line] = {"post_hold_line:int:8", + eDI_MP_post_hold_line, 8}, + [eDI_MP_post_urgent] = {"post_urgent:int:1", + eDI_MP_post_urgent, 1}, + [eDI_MP_di_printk_flag] = {"di_printk_flag:uint", + eDI_MP_di_printk_flag, 0}, + [eDI_MP_force_recovery] = {"force_recovery:uint:1", + eDI_MP_force_recovery, 1}, +#if 0 + [eDI_MP_debug_blend_mode] = {"debug_blend_mode:int:-1", + eDI_MP_debug_blend_mode, -1}, +#endif + [eDI_MP_di_dbg_mask] = {"di_dbg_mask:uint:0x02", + eDI_MP_di_dbg_mask, 2}, + [eDI_MP_nr_done_check_cnt] = {"nr_done_check_cnt:uint:5", + eDI_MP_nr_done_check_cnt, 5}, + [eDI_MP_pre_hsc_down_en] = {"pre_hsc_down_en:bool:0", + eDI_MP_pre_hsc_down_en, 0}, + [eDI_MP_pre_hsc_down_width] = {"pre_hsc_down_width:int:480", + eDI_MP_pre_hsc_down_width, 480}, + [eDI_MP_show_nrwr] = {"show_nrwr:bool:0", + eDI_MP_show_nrwr, 0}, + + /******deinterlace_hw.c**********/ + [eDI_MP_pq_load_dbg] = {"pq_load_dbg:uint", + eDI_MP_pq_load_dbg, 0}, + [eDI_MP_lmv_lock_win_en] = {"lmv_lock_win_en:bool", + eDI_MP_lmv_lock_win_en, 0}, + [eDI_MP_lmv_dist] = {"lmv_dist:short:5", + eDI_MP_lmv_dist, 5}, + [eDI_MP_pr_mcinfo_cnt] = {"pr_mcinfo_cnt:ushort", + eDI_MP_pr_mcinfo_cnt, 0}, + [eDI_MP_offset_lmv] = {"offset_lmv:short:100", + eDI_MP_offset_lmv, 100}, + [eDI_MP_post_ctrl] = {"post_ctrl:uint", + eDI_MP_post_ctrl, 0}, + [eDI_MP_if2_disable] = {"if2_disable:bool", + eDI_MP_if2_disable, 0}, + [eDI_MP_pre_flag] = {"pre_flag:ushort:2", + eDI_MP_pre_flag, 2}, + [eDI_MP_pre_mif_gate] = {"pre_mif_gate:bool", + eDI_MP_pre_mif_gate, 0}, + [eDI_MP_pre_urgent] = {"pre_urgent:ushort", + eDI_MP_pre_urgent, 0}, + [eDI_MP_pre_hold_line] = {"pre_hold_line:ushort:10", + eDI_MP_pre_hold_line, 10}, + [eDI_MP_pre_ctrl] = {"pre_ctrl:uint", + eDI_MP_pre_ctrl, 0}, + [eDI_MP_line_num_post_frst] = {"line_num_post_frst:ushort:5", + eDI_MP_line_num_post_frst, 5}, + [eDI_MP_line_num_pre_frst] = {"line_num_pre_frst:ushort:5", + eDI_MP_line_num_pre_frst, 5}, + [eDI_MP_pd22_flg_calc_en] = {"pd22_flg_calc_en:bool:true", + eDI_MP_pd22_flg_calc_en, 1}, + [eDI_MP_mcen_mode] = {"mcen_mode:ushort:1", + eDI_MP_mcen_mode, 1}, + [eDI_MP_mcuv_en] = {"mcuv_en:ushort:1", + eDI_MP_mcuv_en, 1}, + [eDI_MP_mcdebug_mode] = {"mcdebug_mode:ushort", + eDI_MP_mcdebug_mode, 0}, + [eDI_MP_pldn_ctrl_rflsh] = {"pldn_ctrl_rflsh:uint:1", + eDI_MP_pldn_ctrl_rflsh, 1}, + + [eDI_MP_SUB_DI_E] = {"di end-------", + eDI_MP_SUB_DI_E, 0}, + /**************************************/ + [eDI_MP_SUB_NR_B] = {"nr begin", + eDI_MP_SUB_NR_B, 0}, + [eDI_MP_dnr_en] = {"dnr_en:bool:true", + eDI_MP_dnr_en, 1}, + [eDI_MP_nr2_en] = {"nr2_en:uint:1", + eDI_MP_nr2_en, 1}, + [eDI_MP_cue_en] = {"cue_en:bool:true", + eDI_MP_cue_en, 1}, + [eDI_MP_invert_cue_phase] = {"invert_cue_phase:bool", + eDI_MP_invert_cue_phase, 0}, + [eDI_MP_cue_pr_cnt] = {"cue_pr_cnt:uint", + eDI_MP_cue_pr_cnt, 0}, + [eDI_MP_cue_glb_mot_check_en] = {"cue_glb_mot_check_en:bool:true", + eDI_MP_cue_glb_mot_check_en, 1}, + [eDI_MP_glb_fieldck_en] = {"glb_fieldck_en:bool:true", + eDI_MP_glb_fieldck_en, 1}, + [eDI_MP_dnr_pr] = {"dnr_pr:bool", + eDI_MP_dnr_pr, 0}, + [eDI_MP_dnr_dm_en] = {"dnr_dm_en:bool", + eDI_MP_dnr_dm_en, 0}, + [eDI_MP_SUB_NR_E] = {"nr end-------", + eDI_MP_SUB_NR_E, 0}, + /**************************************/ + [eDI_MP_SUB_PD_B] = {"pd begin", + eDI_MP_SUB_PD_B, 0}, + [eDI_MP_flm22_ratio] = {"flm22_ratio:uint:200", + eDI_MP_flm22_ratio, 200}, + [eDI_MP_pldn_cmb0] = {"pldn_cmb0:uint:1", + eDI_MP_pldn_cmb0, 1}, + [eDI_MP_pldn_cmb1] = {"pldn_cmb1:uint", + eDI_MP_pldn_cmb1, 0}, + [eDI_MP_flm22_sure_num] = {"flm22_sure_num:uint:100", + eDI_MP_flm22_sure_num, 100}, + [eDI_MP_flm22_glbpxlnum_rat] = {"flm22_glbpxlnum_rat:uint:4", + eDI_MP_flm22_glbpxlnum_rat, 4}, + [eDI_MP_flag_di_weave] = {"flag_di_weave:int:1", + eDI_MP_flag_di_weave, 1}, + [eDI_MP_flm22_glbpxl_maxrow] = {"flm22_glbpxl_maxrow:uint:16", + eDI_MP_flm22_glbpxl_maxrow, 16}, + [eDI_MP_flm22_glbpxl_minrow] = {"flm22_glbpxl_minrow:uint:3", + eDI_MP_flm22_glbpxl_minrow, 3}, + [eDI_MP_cmb_3point_rnum] = {"cmb_3point_rnum:uint", + eDI_MP_cmb_3point_rnum, 0}, + [eDI_MP_cmb_3point_rrat] = {"cmb_3point_rrat:unit:32", + eDI_MP_cmb_3point_rrat, 32}, + /********************************/ + [eDI_MP_pr_pd] = {"pr_pd:uint", + eDI_MP_pr_pd, 0}, + [eDI_MP_prt_flg] = {"prt_flg:bool", + eDI_MP_prt_flg, 0}, + [eDI_MP_flmxx_maybe_num] = {"flmxx_maybe_num:uint:15", + /* if flmxx level > flmxx_maybe_num */ + /* mabye flmxx: when 2-2 3-2 not detected */ + eDI_MP_flmxx_maybe_num, 15}, + [eDI_MP_flm32_mim_frms] = {"flm32_mim_frms:int:6", + eDI_MP_flm32_mim_frms, 6}, + [eDI_MP_flm22_dif01a_flag] = {"flm22_dif01a_flag:int:1", + eDI_MP_flm22_dif01a_flag, 1}, + [eDI_MP_flm22_mim_frms] = {"flm22_mim_frms:int:60", + eDI_MP_flm22_mim_frms, 60}, + [eDI_MP_flm22_mim_smfrms] = {"flm22_mim_smfrms:int:40", + eDI_MP_flm22_mim_smfrms, 40}, + [eDI_MP_flm32_f2fdif_min0] = {"flm32_f2fdif_min0:int:11", + eDI_MP_flm32_f2fdif_min0, 11}, + [eDI_MP_flm32_f2fdif_min1] = {"flm32_f2fdif_min1:int:11", + eDI_MP_flm32_f2fdif_min1, 11}, + [eDI_MP_flm32_chk1_rtn] = {"flm32_chk1_rtn:int:25", + eDI_MP_flm32_chk1_rtn, 25}, + [eDI_MP_flm32_ck13_rtn] = {"flm32_ck13_rtn:int:8", + eDI_MP_flm32_ck13_rtn, 8}, + [eDI_MP_flm32_chk2_rtn] = {"flm32_chk2_rtn:int:16", + eDI_MP_flm32_chk2_rtn, 16}, + [eDI_MP_flm32_chk3_rtn] = {"flm32_chk3_rtn:int:16", + eDI_MP_flm32_chk3_rtn, 16}, + [eDI_MP_flm32_dif02_ratio] = {"flm32_dif02_ratio:int:8", + eDI_MP_flm32_dif02_ratio, 8}, + [eDI_MP_flm22_chk20_sml] = {"flm22_chk20_sml:int:6", + eDI_MP_flm22_chk20_sml, 6}, + [eDI_MP_flm22_chk21_sml] = {"flm22_chk21_sml:int:6", + eDI_MP_flm22_chk21_sml, 6}, + [eDI_MP_flm22_chk21_sm2] = {"flm22_chk21_sm2:int:10", + eDI_MP_flm22_chk21_sm2, 10}, + [eDI_MP_flm22_lavg_sft] = {"flm22_lavg_sft:int:4", + eDI_MP_flm22_lavg_sft, 4}, + [eDI_MP_flm22_lavg_lg] = {"flm22_lavg_lg:int:24", + eDI_MP_flm22_lavg_lg, 24}, + [eDI_MP_flm22_stl_sft] = {"flm22_stl_sft:int:7", + eDI_MP_flm22_stl_sft, 7}, + [eDI_MP_flm22_chk5_avg] = {"flm22_chk5_avg:int:50", + eDI_MP_flm22_chk5_avg, 50}, + [eDI_MP_flm22_chk6_max] = {"flm22_chk6_max:int:20", + eDI_MP_flm22_chk6_max, 20}, + [eDI_MP_flm22_anti_chk1] = {"flm22_anti_chk1:int:61", + eDI_MP_flm22_anti_chk1, 61}, + [eDI_MP_flm22_anti_chk3] = {"flm22_anti_chk3:int:140", + eDI_MP_flm22_anti_chk3, 140}, + [eDI_MP_flm22_anti_chk4] = {"flm22_anti_chk4:int:128", + eDI_MP_flm22_anti_chk4, 128}, + [eDI_MP_flm22_anti_ck140] = {"flm22_anti_ck140:int:32", + eDI_MP_flm22_anti_ck140, 32}, + [eDI_MP_flm22_anti_ck141] = {"flm22_anti_ck141:int:80", + eDI_MP_flm22_anti_ck141, 80}, + [eDI_MP_flm22_frmdif_max] = {"flm22_frmdif_max:int:50", + eDI_MP_flm22_frmdif_max, 50}, + [eDI_MP_flm22_flddif_max] = {"flm22_flddif_max:int:100", + eDI_MP_flm22_flddif_max, 100}, + [eDI_MP_flm22_minus_cntmax] = {"flm22_minus_cntmax:int:2", + eDI_MP_flm22_minus_cntmax, 2}, + [eDI_MP_flagdif01chk] = {"flagdif01chk:int:1", + eDI_MP_flagdif01chk, 1}, + [eDI_MP_dif01_ratio] = {"dif01_ratio:int:10", + eDI_MP_dif01_ratio, 10}, + /*************vof_soft_top**************/ + [eDI_MP_cmb32_blw_wnd] = {"cmb32_blw_wnd:int:180", + eDI_MP_cmb32_blw_wnd, 180}, + [eDI_MP_cmb32_wnd_ext] = {"cmb32_wnd_ext:int:11", + eDI_MP_cmb32_wnd_ext, 11}, + [eDI_MP_cmb32_wnd_tol] = {"cmb32_wnd_tol:int:4", + eDI_MP_cmb32_wnd_tol, 4}, + [eDI_MP_cmb32_frm_nocmb] = {"cmb32_frm_nocmb:int:40", + eDI_MP_cmb32_frm_nocmb, 40}, + [eDI_MP_cmb32_min02_sft] = {"cmb32_min02_sft:int:7", + eDI_MP_cmb32_min02_sft, 7}, + [eDI_MP_cmb32_cmb_tol] = {"cmb32_cmb_tol:int:10", + eDI_MP_cmb32_cmb_tol, 10}, + [eDI_MP_cmb32_avg_dff] = {"cmb32_avg_dff:int:48", + eDI_MP_cmb32_avg_dff, 48}, + [eDI_MP_cmb32_smfrm_num] = {"cmb32_smfrm_num:int:4", + eDI_MP_cmb32_smfrm_num, 4}, + [eDI_MP_cmb32_nocmb_num] = {"cmb32_nocmb_num:int:20", + eDI_MP_cmb32_nocmb_num, 20}, + [eDI_MP_cmb22_gcmb_rnum] = {"cmb22_gcmb_rnum:int:8", + eDI_MP_cmb22_gcmb_rnum, 8}, + [eDI_MP_flmxx_cal_lcmb] = {"flmxx_cal_lcmb:int:1", + eDI_MP_flmxx_cal_lcmb, 1}, + [eDI_MP_flm2224_stl_sft] = {"flm2224_stl_sft:int:7", + eDI_MP_flm2224_stl_sft, 7}, + [eDI_MP_SUB_PD_E] = {"pd end------", + eDI_MP_SUB_PD_E, 0}, + /**************************************/ + [eDI_MP_SUB_MTN_B] = {"mtn begin", + eDI_MP_SUB_MTN_B, 0}, + [eDI_MP_force_lev] = {"force_lev:int:0xff", + eDI_MP_force_lev, 0xff}, + [eDI_MP_dejaggy_flag] = {"dejaggy_flag:int:-1", + eDI_MP_dejaggy_flag, -1}, + [eDI_MP_dejaggy_enable] = {"dejaggy_enable:int:1", + eDI_MP_dejaggy_enable, 1}, + [eDI_MP_cmb_adpset_cnt] = {"cmb_adpset_cnt:int", + eDI_MP_cmb_adpset_cnt, 0}, + [eDI_MP_cmb_num_rat_ctl4] = {"cmb_num_rat_ctl4:int:64:0~255", + eDI_MP_cmb_num_rat_ctl4, 64}, + [eDI_MP_cmb_rat_ctl4_minthd] = {"cmb_rat_ctl4_minthd:int:64", + eDI_MP_cmb_rat_ctl4_minthd, 64}, + [eDI_MP_small_local_mtn] = {"small_local_mtn:uint:70", + eDI_MP_small_local_mtn, 70}, + [eDI_MP_di_debug_readreg] = {"di_debug_readreg:int", + eDI_MP_di_debug_readreg, 0}, + [eDI_MP_SUB_MTN_E] = {"mtn end----", + eDI_MP_SUB_MTN_E, 0}, + /**************************************/ + [eDI_MP_SUB_3D_B] = {"3d begin", + eDI_MP_SUB_3D_B, 0}, + [eDI_MP_chessbd_vrate] = {"chessbd_vrate:int:29", + eDI_MP_chessbd_vrate, 29}, + [eDI_MP_det3d_debug] = {"det3d_debug:bool:0", + eDI_MP_det3d_debug, 0}, + [eDI_MP_SUB_3D_E] = {"3d begin", + eDI_MP_SUB_3D_E, 0}, + + /**************************************/ + [eDI_MP_UI_T_END] = {"module para top end ", eDI_MP_UI_T_END, 0}, +}; + +bool di_mp_uit_check(unsigned int idx) +{ + unsigned int tsize; + + tsize = ARRAY_SIZE(di_mp_ui_top); + if (idx >= tsize) { + PR_ERR("%s:err:overflow:%d->%d\n", + __func__, idx, tsize); + return false; + } + if (idx != di_mp_ui_top[idx].id) { + PR_ERR("%s:err:not map:%d->%d\n", + __func__, idx, di_mp_ui_top[idx].id); + return false; + } + dbg_init("\t%-15s=%d\n", di_mp_ui_top[idx].name, + di_mp_ui_top[idx].default_val); + return true; +} + +char *di_mp_uit_get_name(enum eDI_MP_UI_T idx) +{ + return di_mp_ui_top[idx].name; +} + +void di_mp_uit_init_val(void) +{ + int i; + + for (i = eDI_MP_UI_T_BEGIN; i < eDI_MP_UI_T_END; i++) { + if (!di_mp_uit_check(i)) + continue; + di_mp_uit_set(i, di_mp_ui_top[i].default_val); + } +} + +int di_mp_uit_get(enum eDI_MP_UI_T idx) +{ + return get_datal()->mp_uit[idx]; +} + +void di_mp_uit_set(enum eDI_MP_UI_T idx, int val) +{ + get_datal()->mp_uit[idx] = val; +} + +/************************************** + * + * module para x + * unsigned int + **************************************/ + +const struct di_mp_uix_s di_mpx[] = { + /*same order with enum eDI_MP_UI*/ + + /* module para for channel x*/ + [eDI_MP_UIX_BEGIN] = {"module para x begin ", eDI_MP_UIX_BEGIN, 0}, + /*debug: run_flag*/ + [eDI_MP_UIX_RUN_FLG] = {"run_flag(0:run;1:pause;2:step)", + eDI_MP_UIX_RUN_FLG, DI_RUN_FLAG_RUN}, + [eDI_MP_UIX_END] = {"module para x end ", eDI_MP_UIX_END, 0}, + +}; + +bool di_mp_uix_check(unsigned int idx) +{ + unsigned int tsize; + + tsize = ARRAY_SIZE(di_mpx); + if (idx >= tsize) { + PR_ERR("%s:err:overflow:%d->%d\n", + __func__, idx, tsize); + return false; + } + if (idx != di_mpx[idx].id) { + PR_ERR("%s:err:not map:%d->%d\n", + __func__, idx, di_mpx[idx].id); + return false; + } + dbg_init("\t%-15s=%d\n", di_mpx[idx].name, di_mpx[idx].default_val); + + return true; +} + +char *di_mp_uix_get_name(enum eDI_MP_UIX_T idx) +{ + return di_mpx[idx].name; +} + +void di_mp_uix_init_val(void) +{ + int i, ch; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + dbg_init("%s:ch[%d]\n", __func__, ch); + for (i = eDI_MP_UIX_BEGIN; i < eDI_MP_UIX_END; i++) { + if (ch == 0) { + if (!di_mp_uix_check(i)) + continue; + } + di_mp_uix_set(ch, i, di_mpx[i].default_val); + } + } +} + +unsigned int di_mp_uix_get(unsigned int ch, enum eDI_MP_UIX_T idx) +{ + return get_datal()->ch_data[ch].mp_uix[idx]; +} + +void di_mp_uix_set(unsigned int ch, enum eDI_MP_UIX_T idx, unsigned int val) +{ + get_datal()->ch_data[ch].mp_uix[idx] = val; +} + +bool di_is_pause(unsigned int ch) +{ + unsigned int run_flag; + + run_flag = di_mp_uix_get(ch, eDI_MP_UIX_RUN_FLG); + + if (run_flag == DI_RUN_FLAG_PAUSE || + run_flag == DI_RUN_FLAG_STEP_DONE) + return true; + + return false; +} + +void di_pause_step_done(unsigned int ch) +{ + unsigned int run_flag; + + run_flag = di_mp_uix_get(ch, eDI_MP_UIX_RUN_FLG); + if (run_flag == DI_RUN_FLAG_STEP) { + di_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG, + DI_RUN_FLAG_STEP_DONE); + } +} + +void di_pause(unsigned int ch, bool on) +{ + pr_info("%s:%d\n", __func__, on); + if (on) + di_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG, + DI_RUN_FLAG_PAUSE); + else + di_mp_uix_set(ch, eDI_MP_UIX_RUN_FLG, + DI_RUN_FLAG_RUN); +} + +/************************************** + * + * summmary variable + * + **************************************/ +const struct di_sum_s di_sum_tab[] = { + /*video_peek_cnt*/ + [eDI_SUM_O_PEEK_CNT] = {"o_peek_cnt", eDI_SUM_O_PEEK_CNT, 0}, + /*di_reg_unreg_cnt*/ + [eDI_SUM_REG_UNREG_CNT] = { + "di_reg_unreg_cnt", eDI_SUM_REG_UNREG_CNT, 100}, + + [eDI_SUM_NUB] = {"end", eDI_SUM_NUB, 0}, +}; + +unsigned int di_sum_get_tab_size(void) +{ + return ARRAY_SIZE(di_sum_tab); +} + +bool di_sum_check(unsigned int ch, enum eDI_SUM id) +{ + unsigned int tsize; + + tsize = ARRAY_SIZE(di_sum_tab); + + if (id >= tsize) { + PR_ERR("%s:err:overflow:tsize[%d],id[%d]\n", + __func__, tsize, id); + return false; + } + if (di_sum_tab[id].index != id) { + PR_ERR("%s:err:table:id[%d],tab_id[%d]\n", + __func__, id, di_sum_tab[id].index); + return false; + } + return true; +} + +void di_sum_reg_init(unsigned int ch) +{ + unsigned int tsize; + int i; + + tsize = ARRAY_SIZE(di_sum_tab); + + dbg_init("%s:ch[%d]\n", __func__, ch); + for (i = 0; i < tsize; i++) { + if (!di_sum_check(ch, i)) + continue; + dbg_init("\t:%d:name:%s,%d\n", i, di_sum_tab[i].name, + di_sum_tab[i].default_val); + di_sum_set_l(ch, i, di_sum_tab[i].default_val); + } +} + +void di_sum_get_info(unsigned int ch, enum eDI_SUM id, char **name, + unsigned int *pval) +{ + *name = di_sum_tab[id].name; + *pval = di_sum_get(ch, id); +} + +void di_sum_set(unsigned int ch, enum eDI_SUM id, unsigned int val) +{ + if (!di_sum_check(ch, id)) + return; + + di_sum_set_l(ch, id, val); +} + +unsigned int di_sum_inc(unsigned int ch, enum eDI_SUM id) +{ + if (!di_sum_check(ch, id)) + return 0; + return di_sum_inc_l(ch, id); +} + +unsigned int di_sum_get(unsigned int ch, enum eDI_SUM id) +{ + if (!di_sum_check(ch, id)) + return 0; + return di_sum_get_l(ch, id); +} + +/****************************/ +/*call by event*/ +/****************************/ +void dip_even_reg_init_val(unsigned int ch) +{ +} + +void dip_even_unreg_val(unsigned int ch) +{ +} + +/****************************/ +static void dip_cma_init_val(void) +{ + unsigned int ch; + struct di_mng_s *pbm = get_bufmng(); + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + /* CMA state */ + atomic_set(&pbm->cma_mem_state[ch], eDI_CMA_ST_IDL); + + /* CMA reg/unreg cmd */ + pbm->cma_reg_cmd[ch] = 0; + } +} + +void dip_cma_close(void) +{ + unsigned int ch; + struct di_mng_s *pbm = get_bufmng(); + + if (dip_cma_st_is_idl_all()) + return; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + if (!dip_cma_st_is_idle(ch)) { + dim_cma_top_release(ch); + pr_info("%s:force release ch[%d]", __func__, ch); + atomic_set(&pbm->cma_mem_state[ch], eDI_CMA_ST_IDL); + + pbm->cma_reg_cmd[ch] = 0; + } + } +} + +static void dip_wq_cma_handler(struct work_struct *work) +{ + unsigned int ch; + struct di_mng_s *pbm = get_bufmng(); + enum eDI_CMA_ST cma_st; + bool do_flg; + + pr_info("%s:start\n", __func__); + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + do_flg = false; + cma_st = dip_cma_get_st(ch); + switch (cma_st) { + case eDI_CMA_ST_IDL: + if (pbm->cma_reg_cmd[ch]) { + do_flg = true; + /*set:alloc:*/ + atomic_set(&pbm->cma_mem_state[ch], + eDI_CMA_ST_ALLOC); + if (dim_cma_top_alloc(ch)) { + atomic_set(&pbm->cma_mem_state[ch], + eDI_CMA_ST_READY); + } + } + break; + case eDI_CMA_ST_READY: + if (!pbm->cma_reg_cmd[ch]) { + do_flg = true; + atomic_set(&pbm->cma_mem_state[ch], + eDI_CMA_ST_RELEASE); + dim_cma_top_release(ch); + atomic_set(&pbm->cma_mem_state[ch], + eDI_CMA_ST_IDL); + } + break; + case eDI_CMA_ST_ALLOC: /*do*/ + case eDI_CMA_ST_RELEASE:/*do*/ + default: + break; + } + if (!do_flg) + pr_info("\tch[%d],do nothing[%d]\n", ch, cma_st); + else + task_send_ready(); + } + pr_info("%s:end\n", __func__); +} + +static void dip_wq_prob(void) +{ + struct di_mng_s *pbm = get_bufmng(); + + pbm->wq_cma = create_singlethread_workqueue("deinterlace"); + INIT_WORK(&pbm->wq_work, dip_wq_cma_handler); +} + +static void dip_wq_ext(void) +{ + struct di_mng_s *pbm = get_bufmng(); + + cancel_work_sync(&pbm->wq_work); + destroy_workqueue(pbm->wq_cma); + pr_info("%s:finish\n", __func__); +} + +void dip_wq_cma_run(unsigned char ch, bool reg_cmd) +{ + struct di_mng_s *pbm = get_bufmng(); + + if (reg_cmd) + pbm->cma_reg_cmd[ch] = 1; + else + pbm->cma_reg_cmd[ch] = 0; + + queue_work(pbm->wq_cma, &pbm->wq_work); +} + +bool dip_cma_st_is_ready(unsigned int ch) +{ + struct di_mng_s *pbm = get_bufmng(); + bool ret = false; + + if (atomic_read(&pbm->cma_mem_state[ch]) == eDI_CMA_ST_READY) + ret = true; + + return ret; +} + +bool dip_cma_st_is_idle(unsigned int ch) +{ + struct di_mng_s *pbm = get_bufmng(); + bool ret = false; + + if (atomic_read(&pbm->cma_mem_state[ch]) == eDI_CMA_ST_IDL) + ret = true; + + return ret; +} + +bool dip_cma_st_is_idl_all(void) +{ + unsigned int ch; + struct di_mng_s *pbm = get_bufmng(); + bool ret = true; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + if (atomic_read(&pbm->cma_mem_state[ch]) != eDI_CMA_ST_IDL) { + ret = true; + break; + } + } + return ret; +} + +enum eDI_CMA_ST dip_cma_get_st(unsigned int ch) +{ + struct di_mng_s *pbm = get_bufmng(); + + return atomic_read(&pbm->cma_mem_state[ch]); +} + +const char * const di_cma_state_name[] = { + "IDLE", + "do_alloc", + "READY", + "do_release", +}; + +const char *di_cma_dbg_get_st_name(unsigned int ch) +{ + enum eDI_CMA_ST st = dip_cma_get_st(ch); + const char *p = ""; + + if (st <= eDI_CMA_ST_RELEASE) + p = di_cma_state_name[st]; + return p; +} + +void dip_cma_st_set_ready_all(void) +{ + unsigned int ch; + struct di_mng_s *pbm = get_bufmng(); + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) + atomic_set(&pbm->cma_mem_state[ch], eDI_CMA_ST_READY); +} + +/****************************/ +/*channel STATE*/ +/****************************/ +void dip_chst_set(unsigned int ch, enum eDI_TOP_STATE chSt) +{ + struct di_mng_s *pbm = get_bufmng(); + + atomic_set(&pbm->ch_state[ch], chSt); +} + +enum eDI_TOP_STATE dip_chst_get(unsigned int ch) +{ + struct di_mng_s *pbm = get_bufmng(); + + return atomic_read(&pbm->ch_state[ch]); +} + +void dip_chst_init(void) +{ + unsigned int ch; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) + dip_chst_set(ch, eDI_TOP_STATE_IDLE); +} + +bool dip_event_reg_chst(unsigned int ch) +{ + enum eDI_TOP_STATE chst; + struct di_pre_stru_s *ppre = get_pre_stru(ch); + bool err_flg = false; + bool ret = true; + + dbg_dbg("%s:ch[%d]\n", __func__, ch); + + chst = dip_chst_get(ch); +#if 0 /*move*/ + if (chst > eDI_TOP_STATE_NOPROB) + set_flag_trig_unreg(ch, false); +#endif + switch (chst) { + case eDI_TOP_STATE_IDLE: + + queue_init2(ch); + di_que_init(ch); + di_vframe_reg(ch); + + dip_chst_set(ch, eDI_TOP_STATE_REG_STEP1); + task_send_cmd(LCMD1(eCMD_REG, ch)); + dbg_dbg("reg ok\n"); + break; + case eDI_TOP_STATE_REG_STEP1: + case eDI_TOP_STATE_REG_STEP1_P1: + case eDI_TOP_STATE_REG_STEP2: + case eDI_TOP_STATE_READY: + case eDI_TOP_STATE_BYPASS: + PR_WARN("have reg\n"); + ret = false; + break; + case eDI_TOP_STATE_UNREG_STEP1: + case eDI_TOP_STATE_UNREG_STEP2: + /*wait*/ + ppre->reg_req_flag_cnt = 0; + while (dip_chst_get(ch) != eDI_TOP_STATE_IDLE) { + usleep_range(10000, 10001); + if (ppre->reg_req_flag_cnt++ > + dim_get_reg_unreg_cnt()) { + dim_reg_timeout_inc(); + PR_ERR("%s,ch[%d] reg timeout!!!\n", + __func__, ch); + err_flg = true; + ret = false; + break; + } + } + if (!err_flg) { + /*same as IDLE*/ + queue_init2(ch); + di_que_init(ch); + di_vframe_reg(ch); + + dip_chst_set(ch, eDI_TOP_STATE_REG_STEP1); + task_send_cmd(LCMD1(eCMD_REG, ch)); + dbg_dbg("reg retry ok\n"); + } + break; + case eDI_TOP_STATE_NOPROB: + default: + ret = false; + PR_ERR("err: not prob[%d]\n", chst); + + break; + } + + return ret; +} + +bool dip_event_unreg_chst(unsigned int ch) +{ + enum eDI_TOP_STATE chst, chst2; + struct di_pre_stru_s *ppre = get_pre_stru(ch); + bool ret = false; + bool err_flg = false; + unsigned int cnt; + + chst = dip_chst_get(ch); + dbg_reg("%s:ch[%d]:%s\n", __func__, ch, dip_chst_get_name(chst)); + #if 0 + if (chst > eDI_TOP_STATE_IDLE) + set_reg_flag(ch, false);/*set_flag_trig_unreg(ch, true);*/ + #endif + if (chst > eDI_TOP_STATE_NOPROB) + set_flag_trig_unreg(ch, true); + + switch (chst) { + case eDI_TOP_STATE_READY: + + di_vframe_unreg(ch); + /*trig unreg*/ + dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP1); + task_send_cmd(LCMD1(eCMD_UNREG, ch)); + /*debug only di_dbg = di_dbg|DBG_M_TSK;*/ + + /*wait*/ + ppre->unreg_req_flag_cnt = 0; + chst2 = dip_chst_get(ch); + + while (chst2 != eDI_TOP_STATE_IDLE) { + task_send_ready(); + usleep_range(10000, 10001); + /*msleep(5);*/ + if (ppre->unreg_req_flag_cnt++ + > dim_get_reg_unreg_cnt()) { + dim_reg_timeout_inc(); + PR_ERR("%s:ch[%d] unreg timeout!!!\n", + __func__, ch); + /*dim_unreg_process();*/ + err_flg = true; + break; + } + #if 0 /*debug only*/ + dbg_reg("\tch[%d]:s[%s],ecnt[%d]\n", + ch, + dip_chst_get_name(chst2), + ppre->unreg_req_flag_cnt); + #endif + chst2 = dip_chst_get(ch); + } + + /*debug only di_dbg = di_dbg & (~DBG_M_TSK);*/ + dbg_reg("%s:ch[%d] ready end\n", __func__, ch); + #if 0 + if (!err_flg) + set_reg_flag(ch, false); + #endif + break; + case eDI_TOP_STATE_BYPASS: + /*from bypass complet to unreg*/ + di_vframe_unreg(ch); + di_unreg_variable(ch); + + set_reg_flag(ch, false); + if (!get_reg_flag_all()) { + di_unreg_setting(); + dpre_init(); + dpost_init(); + } + dip_chst_set(ch, eDI_TOP_STATE_IDLE); + ret = true; + + break; + case eDI_TOP_STATE_IDLE: + PR_WARN("have unreg\n"); + break; + case eDI_TOP_STATE_REG_STEP1: + dbg_dbg("%s:in reg step1\n", __func__); + di_vframe_unreg(ch); + set_reg_flag(ch, false); + dip_chst_set(ch, eDI_TOP_STATE_IDLE); + + ret = true; + break; + case eDI_TOP_STATE_REG_STEP1_P1: + /*wait:*/ + cnt = 0; + while (chst2 == eDI_TOP_STATE_REG_STEP1_P1 || cnt < 5) { + task_send_ready(); + usleep_range(3000, 3001); + cnt++; + } + if (cnt >= 5) + PR_ERR("%s:ch[%d] in p1 timeout\n", __func__, ch); + + set_reg_flag(ch, false); + + di_vframe_unreg(ch); + /*trig unreg*/ + dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP1); + task_send_cmd(LCMD1(eCMD_UNREG, ch)); + /*debug only di_dbg = di_dbg|DBG_M_TSK;*/ + + /*wait*/ + ppre->unreg_req_flag_cnt = 0; + chst2 = dip_chst_get(ch); + + while (chst2 != eDI_TOP_STATE_IDLE) { + task_send_ready(); + usleep_range(10000, 10001); + /*msleep(5);*/ + if (ppre->unreg_req_flag_cnt++ + > dim_get_reg_unreg_cnt()) { + dim_reg_timeout_inc(); + PR_ERR("%s:ch[%d] unreg timeout!!!\n", + __func__, + ch); + /*di_unreg_process();*/ + err_flg = true; + break; + } + + chst2 = dip_chst_get(ch); + } + + /*debug only di_dbg = di_dbg & (~DBG_M_TSK);*/ + dbg_reg("%s:ch[%d] ready end\n", __func__, ch); + ret = true; + + break; + case eDI_TOP_STATE_REG_STEP2: + di_vframe_unreg(ch); + di_unreg_variable(ch); + set_reg_flag(ch, false); + if (!get_reg_flag_all()) { + di_unreg_setting(); + dpre_init(); + dpost_init(); + } + + dip_chst_set(ch, eDI_TOP_STATE_IDLE); + + ret = true; + break; + case eDI_TOP_STATE_UNREG_STEP1: + case eDI_TOP_STATE_UNREG_STEP2: + task_send_cmd(LCMD1(eCMD_UNREG, ch)); + + /*wait*/ + ppre->unreg_req_flag_cnt = 0; + while (dip_chst_get(ch) != eDI_TOP_STATE_IDLE) { + usleep_range(10000, 10001); + if (ppre->unreg_req_flag_cnt++ > + dim_get_reg_unreg_cnt()) { + dim_reg_timeout_inc(); + PR_ERR("%s:unreg_reg_flag timeout!!!\n", + __func__); + di_vframe_unreg(ch); + err_flg = true; + break; + } + } + break; + case eDI_TOP_STATE_NOPROB: + default: + PR_ERR("err: not prob[%d]\n", chst); + break; + } + if (err_flg) + ret = false; + + return ret; +} + +/*process for reg and unreg cmd*/ +void dip_chst_process_reg(unsigned int ch) +{ + enum eDI_TOP_STATE chst; + struct vframe_s *vframe; + struct di_pre_stru_s *ppre = get_pre_stru(ch); + bool reflesh = true; + + while (reflesh) { + reflesh = false; + + chst = dip_chst_get(ch); + + /*dbg_reg("%s:ch[%d]%s\n", __func__, ch, dip_chst_get_name(chst));*/ + + switch (chst) { + case eDI_TOP_STATE_NOPROB: + case eDI_TOP_STATE_IDLE: + break; + case eDI_TOP_STATE_REG_STEP1:/*wait peek*/ + vframe = pw_vf_peek(ch); + + if (vframe) { + dim_tr_ops.pre_get(vframe->omx_index); + set_flag_trig_unreg(ch, false); + #if 0 + di_reg_variable(ch); + + /*?how about bypass ?*/ + if (ppre->bypass_flag) { + /* complete bypass */ + set_bypass2_complete(ch, true); + if (!get_reg_flag_all()) { + /*first channel reg*/ + dpre_init(); + dpost_init(); + di_reg_setting(ch, vframe); + } + dip_chst_set(ch, eDI_TOP_STATE_BYPASS); + set_reg_flag(ch, true); + } else { + set_bypass2_complete(ch, false); + if (!get_reg_flag_all()) { + /*first channel reg*/ + dpre_init(); + dpost_init(); + di_reg_setting(ch, vframe); + } + dip_chst_set(ch, eDI_TOP_STATE_REG_STEP2); + } + #else + dip_chst_set(ch, eDI_TOP_STATE_REG_STEP1_P1); + #endif + + reflesh = true; + } + break; + case eDI_TOP_STATE_REG_STEP1_P1: + vframe = pw_vf_peek(ch); + if (!vframe) { + PR_ERR("%s:p1 vfm nop\n", __func__); + dip_chst_set(ch, eDI_TOP_STATE_REG_STEP1); + + break; + } + di_reg_variable(ch, vframe); + /*di_reg_process_irq(ch);*/ /*check if bypass*/ + + /*?how about bypass ?*/ + if (ppre->bypass_flag) { + /* complete bypass */ + set_bypass2_complete(ch, true); + if (!get_reg_flag_all()) { + /*first channel reg*/ + dpre_init(); + dpost_init(); + di_reg_setting(ch, vframe); + } + dip_chst_set(ch, eDI_TOP_STATE_BYPASS); + set_reg_flag(ch, true); + } else { + set_bypass2_complete(ch, false); + if (!get_reg_flag_all()) { + /*first channel reg*/ + dpre_init(); + dpost_init(); + di_reg_setting(ch, vframe); + } + /*this will cause first local buf not alloc*/ + /*dim_bypass_first_frame(ch);*/ + dip_chst_set(ch, eDI_TOP_STATE_REG_STEP2); + /*set_reg_flag(ch, true);*/ + } + + reflesh = true; + break; + case eDI_TOP_STATE_REG_STEP2:/*now no change to do*/ + if (dip_cma_get_st(ch) == eDI_CMA_ST_READY) { + if (di_cfg_top_get(eDI_CFG_first_bypass)) { + if (get_sum_g(ch) == 0) + dim_bypass_first_frame(ch); + else + PR_INF("ch[%d],g[%d]\n", + ch, get_sum_g(ch)); + } + dip_chst_set(ch, eDI_TOP_STATE_READY); + set_reg_flag(ch, true); + /*move to step1 dim_bypass_first_frame(ch);*/ + } + break; + case eDI_TOP_STATE_READY: + + break; + case eDI_TOP_STATE_BYPASS: + /*do nothing;*/ + break; + case eDI_TOP_STATE_UNREG_STEP1: + +#if 0 + if (!get_reg_flag(ch)) { /*need wait pre/post done*/ + dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2); + reflesh = true; + } +#else + /*debug only dbg_reg("%s:UNREG_STEP1\n", __func__);*/ + + if (dpre_can_exit(ch) && dpst_can_exit(ch)) { + dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2); + set_reg_flag(ch, false); + reflesh = true; + } +#endif + break; + case eDI_TOP_STATE_UNREG_STEP2: + /*debug only dbg_reg("%s:ch[%d]:UNREG_STEP2\n",__func__, ch);*/ + di_unreg_variable(ch); + if (!get_reg_flag_all()) { + di_unreg_setting(); + dpre_init(); + dpost_init(); + } + + dip_chst_set(ch, eDI_TOP_STATE_IDLE); + /*debug only dbg_reg("ch[%d]UNREG_STEP2 end\n",ch);*/ + break; + } + } +} + +void dip_chst_process_ch(void) +{ + unsigned int ch; + unsigned int chst; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + chst = dip_chst_get(ch); + switch (chst) { + case eDI_TOP_STATE_REG_STEP2: + if (dip_cma_get_st(ch) == eDI_CMA_ST_READY) { + if (di_cfg_top_get(eDI_CFG_first_bypass)) { + if (get_sum_g(ch) == 0) + dim_bypass_first_frame(ch); + else + PR_INF("ch[%d],g[%d]\n", + ch, get_sum_g(ch)); + } + dip_chst_set(ch, eDI_TOP_STATE_READY); + set_reg_flag(ch, true); + } + break; +#if 1 + case eDI_TOP_STATE_UNREG_STEP1: + if (dpre_can_exit(ch) && dpst_can_exit(ch)) { + dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2); + set_reg_flag(ch, false); + } + + break; +#endif + case eDI_TOP_STATE_UNREG_STEP2: + dbg_reg("%s:ch[%d]:at UNREG_STEP2\n", __func__, ch); + di_unreg_variable(ch); + if (!get_reg_flag_all()) { + di_unreg_setting(); + dpre_init(); + dpost_init(); + } + + dip_chst_set(ch, eDI_TOP_STATE_IDLE); + dbg_reg("ch[%d]STEP2 end\n", ch); + break; + } + } +} + +bool dip_chst_change_2unreg(void) +{ + unsigned int ch; + unsigned int chst; + bool ret = false; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + chst = dip_chst_get(ch); + dbg_poll("[%d]%d\n", ch, chst); + if (chst == eDI_TOP_STATE_UNREG_STEP1) { + dbg_reg("%s:ch[%d]to UNREG_STEP2\n", __func__, ch); + set_reg_flag(ch, false); + dip_chst_set(ch, eDI_TOP_STATE_UNREG_STEP2); + ret = true; + } + } + return ret; +} + +#if 0 +void di_reg_flg_check(void) +{ + int ch; + unsigned int chst; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) + chst = dip_chst_get(ch); +} +#endif + +void dip_hw_process(void) +{ + di_dbg_task_flg = 5; + dpre_process(); + di_dbg_task_flg = 6; + pre_mode_setting(); + di_dbg_task_flg = 7; + dpst_process(); + di_dbg_task_flg = 8; +} + +const char * const di_top_state_name[] = { + "NOPROB", + "IDLE", + "REG_STEP1", + "REG_P1", + "REG_STEP2", + "READY", + "BYPASS", + "UNREG_STEP1", + "UNREG_STEP2", +}; + +const char *dip_chst_get_name_curr(unsigned int ch) +{ + const char *p = ""; + enum eDI_TOP_STATE chst; + + chst = dip_chst_get(ch); + + if (chst < sizeof(di_top_state_name)) + p = di_top_state_name[chst]; + + return p; +} + +const char *dip_chst_get_name(enum eDI_TOP_STATE chst) +{ + const char *p = ""; + + if (chst < sizeof(di_top_state_name)) + p = di_top_state_name[chst]; + + return p; +} + +/**********************************/ +/* TIME OUT CHEKC api*/ +/**********************************/ + +void di_tout_int(struct di_time_out_s *tout, unsigned int thd) +{ + tout->en = false; + tout->timer_start = 0; + tout->timer_thd = thd; +} + +bool di_tout_contr(enum eDI_TOUT_CONTR cmd, struct di_time_out_s *tout) +{ + unsigned long ctimer; + unsigned long diff; + bool ret = false; + + ctimer = cur_to_msecs(); + + switch (cmd) { + case eDI_TOUT_CONTR_EN: + tout->en = true; + tout->timer_start = ctimer; + break; + case eDI_TOUT_CONTR_FINISH: + if (tout->en) { + diff = ctimer - tout->timer_start; + + if (diff > tout->timer_thd) { + tout->over_flow_cnt++; + + if (tout->over_flow_cnt > 0xfffffff0) { + tout->over_flow_cnt = 0; + tout->flg_over = 1; + } + #if 0 + if (tout->do_func) + tout->do_func(); + + #endif + ret = true; + } + tout->en = false; + } + break; + + case eDI_TOUT_CONTR_CHECK: /*if time is overflow, disable timer*/ + if (tout->en) { + diff = ctimer - tout->timer_start; + + if (diff > tout->timer_thd) { + tout->over_flow_cnt++; + + if (tout->over_flow_cnt > 0xfffffff0) { + tout->over_flow_cnt = 0; + tout->flg_over = 1; + } + #if 0 + if (tout->do_func) + tout->do_func(); + + #endif + ret = true; + tout->en = false; + } + } + break; + case eDI_TOUT_CONTR_CLEAR: + tout->en = false; + tout->timer_start = ctimer; + break; + case eDI_TOUT_CONTR_RESET: + tout->en = true; + tout->timer_start = ctimer; + break; + } + + return ret; +} + +const unsigned int di_ch2mask_table[DI_CHANNEL_MAX] = { + DI_BIT0, + DI_BIT1, + DI_BIT2, + DI_BIT3, +}; + +/****************************************/ +/* do_table */ +/****************************************/ + +/*for do_table_working*/ +#define K_DO_TABLE_LOOP_MAX 15 + +const struct do_table_s do_table_def = { + .ptab = NULL, + .data = NULL, + .size = 0, + .op_lst = K_DO_TABLE_ID_STOP, + .op_crr = K_DO_TABLE_ID_STOP, + .do_stop = 0, + .flg_stop = 0, + .do_pause = 0, + .do_step = 0, + .flg_repeat = 0, + +}; + +void do_table_init(struct do_table_s *pdo, + const struct do_table_ops_s *ptable, + unsigned int size_tab) +{ + memcpy(pdo, &do_table_def, sizeof(struct do_table_s)); + + if (ptable) { + pdo->ptab = ptable; + pdo->size = size_tab; + } +} + +/*if change to async?*/ +/* now only call in same thread */ +void do_talbe_cmd(struct do_table_s *pdo, enum eDO_TABLE_CMD cmd) +{ + switch (cmd) { + case eDO_TABLE_CMD_NONE: + pr_info("test:%s\n", __func__); + break; + case eDO_TABLE_CMD_STOP: + pdo->do_stop = true; + break; + case eDO_TABLE_CMD_START: + if (pdo->op_crr == K_DO_TABLE_ID_STOP) { + pdo->op_lst = pdo->op_crr; + pdo->op_crr = K_DO_TABLE_ID_START; + pdo->do_stop = false; + pdo->flg_stop = false; + } else if (pdo->op_crr == K_DO_TABLE_ID_PAUSE) { + pdo->op_crr = pdo->op_lst; + pdo->op_lst = K_DO_TABLE_ID_PAUSE; + pdo->do_pause = false; + } else { + pr_info("crr is [%d], not start\n", pdo->op_crr); + } + break; + case eDO_TABLE_CMD_PAUSE: + if (pdo->op_crr <= K_DO_TABLE_ID_STOP) { + /*do nothing*/ + } else { + pdo->op_crr = pdo->op_lst; + pdo->op_crr = K_DO_TABLE_ID_PAUSE; + pdo->do_pause = true; + } + break; + case eDO_TABLE_CMD_STEP: + pdo->do_step = true; + break; + case eDO_TABLE_CMD_STEP_BACK: + pdo->do_step = false; + break; + default: + break; + } +} + +bool do_table_is_crr(struct do_table_s *pdo, unsigned int state) +{ + if (pdo->op_crr == state) + return true; + return false; +} + +void do_table_working(struct do_table_s *pdo) +{ + const struct do_table_ops_s *pcrr; + unsigned int ret = 0; + unsigned int next; + bool flash = false; + unsigned int cnt = 0; /*proction*/ + unsigned int lst_id; /*dbg only*/ + char *name = ""; /*dbg only*/ + bool need_pr = false; /*dbg only*/ + + if (!pdo || + !pdo->ptab || + pdo->op_crr >= pdo->size) { + PR_ERR("di:err:%s:ovflow:0x%p,0x%p,crr=%d,size=%d\n", + __func__, + pdo, pdo->ptab, + pdo->op_crr, + pdo->size); + return; + } + + pcrr = pdo->ptab + pdo->op_crr; + + if (pdo->name) + name = pdo->name; + /*stop ?*/ + if (pdo->do_stop && + (pcrr->mark & K_DO_TABLE_CAN_STOP)) { + dbg_dt("%s:do stop\n", name); + + /*do stop*/ + if (pcrr->do_stop_op) + pcrr->do_stop_op(pdo->data); + /*set status*/ + pdo->op_lst = pdo->op_crr; + pdo->op_crr = K_DO_TABLE_ID_STOP; + pdo->flg_stop = true; + pdo->do_stop = false; + + return; + } + + /*pause?*/ + if (pdo->op_crr == K_DO_TABLE_ID_STOP || + pdo->op_crr == K_DO_TABLE_ID_PAUSE) + return; + + do { + flash = false; + cnt++; + if (cnt > K_DO_TABLE_LOOP_MAX) { + PR_ERR("di:err:%s:loop more %d\n", name, cnt); + break; + } + + /*stop again? */ + if (pdo->do_stop && + (pcrr->mark & K_DO_TABLE_CAN_STOP)) { + /*do stop*/ + dbg_dt("%s: do stop in loop\n", name); + if (pcrr->do_stop_op) + pcrr->do_stop_op(pdo->data); + /*set status*/ + pdo->op_lst = pdo->op_crr; + pdo->op_crr = K_DO_TABLE_ID_STOP; + pdo->flg_stop = true; + pdo->do_stop = false; + + break; + } + + /*debug:*/ + lst_id = pdo->op_crr; + need_pr = true; + + if (pcrr->con) { + if (pcrr->con(pdo->data)) + ret = pcrr->do_op(pdo->data); + else + break; + + } else { + ret = pcrr->do_op(pdo->data); + dbg_dt("do_table:do:%d:ret=0x%x\n", pcrr->id, ret); + } + + /*not finish, keep current status*/ + if ((ret & K_DO_TABLE_R_B_FINISH) == 0) { + dbg_dt("%s:not finish,wait\n", __func__); + break; + } + + /*fix to next */ + if (ret & K_DO_TABLE_R_B_NEXT) { + pdo->op_lst = pdo->op_crr; + pdo->op_crr++; + if (pdo->op_crr >= pdo->size) { + pdo->op_crr = pdo->flg_repeat ? + K_DO_TABLE_ID_START + : K_DO_TABLE_ID_STOP; + dbg_dt("%s:to end,%d\n", __func__, + pdo->op_crr); + break; + } + /*return;*/ + flash = true; + } else { + next = ((ret & K_DO_TABLE_R_B_OTHER) >> + K_DO_TABLE_R_B_OTHER_SHIFT); + if (next < pdo->size) { + pdo->op_lst = pdo->op_crr; + pdo->op_crr = next; + if (next > K_DO_TABLE_ID_STOP) + flash = true; + else + flash = false; + } else { + PR_ERR("%s: next[%d] err:\n", + __func__, next); + } + } + /*debug 1:*/ + need_pr = false; + if (lst_id != pdo->op_crr) { + dbg_dt("do_table:%s:%s->%s\n", pdo->name, + pdo->ptab[lst_id].name, + pdo->ptab[pdo->op_crr].name); + } + + pcrr = pdo->ptab + pdo->op_crr; + } while (flash && !pdo->do_step); + + /*debug 2:*/ + if (need_pr) { + if (lst_id != pdo->op_crr) { + dbg_dt("do_table2:%s:%s->%s\n", pdo->name, + pdo->ptab[lst_id].name, + pdo->ptab[pdo->op_crr].name); + } + } +} + +/**********************************/ + +/****************************/ +void dip_init_value_reg(unsigned int ch) +{ + struct di_post_stru_s *ppost; + struct di_buf_s *keep_post_buf; + struct di_pre_stru_s *ppre = get_pre_stru(ch); + + pr_info("%s:\n", __func__); + + /*post*/ + ppost = get_post_stru(ch); + /*keep buf:*/ + keep_post_buf = ppost->keep_buf_post; + + memset(ppost, 0, sizeof(struct di_post_stru_s)); + ppost->next_canvas_id = 1; + ppost->keep_buf_post = keep_post_buf; + + /*pre*/ + memset(ppre, 0, sizeof(struct di_pre_stru_s)); +} + +static bool dip_init_value(void) +{ + unsigned int ch; + struct di_post_stru_s *ppost; + struct di_mm_s *mm = dim_mm_get(); + bool ret = false; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + ppost = get_post_stru(ch); + memset(ppost, 0, sizeof(struct di_post_stru_s)); + ppost->next_canvas_id = 1; + + /*que*/ + ret = di_que_alloc(ch); + } + set_current_channel(0); + + /*mm cfg*/ + mm->cfg.di_h = 1080; + mm->cfg.di_w = 1920; + mm->cfg.num_local = MAX_LOCAL_BUF_NUM; + mm->cfg.num_post = MAX_POST_BUF_NUM; + /*mm sts*/ + mm->sts.mem_start = 0; + mm->sts.mem_size = 0; + mm->sts.total_pages = NULL; + mm->sts.flag_cma = 0; + + return ret; +} + +/****************************************** + * pq ops + *****************************************/ +void dip_init_pq_ops(void) +{ + di_attach_ops_pulldown(&get_datal()->ops_pd); + di_attach_ops_3d(&get_datal()->ops_3d); + di_attach_ops_nr(&get_datal()->ops_nr); + di_attach_ops_mtn(&get_datal()->ops_mtn); + + dim_attach_to_local(); +} + +/**********************************/ +void dip_clean_value(void) +{ + unsigned int ch; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + /*que*/ + di_que_release(ch); + } +} + +bool dip_prob(void) +{ + bool ret = true; + + ret = dip_init_value(); + + di_cfgx_init_val(); + di_cfg_top_init_val(); + di_mp_uit_init_val(); + di_mp_uix_init_val(); + + dev_vframe_init(); + didbg_fs_init(); + dip_wq_prob(); + dip_cma_init_val(); + dip_chst_init(); + + dpre_init(); + dpost_init(); + + dip_init_pq_ops(); + + return ret; +} + +void dip_exit(void) +{ + dip_wq_ext(); + dev_vframe_exit(); + dip_clean_value(); + didbg_fs_exit(); +} + diff --git a/drivers/amlogic/media/di_multi/di_prc.h b/drivers/amlogic/media/di_multi/di_prc.h new file mode 100644 index 0000000..8083bc4 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_prc.h @@ -0,0 +1,131 @@ +/* + * drivers/amlogic/media/di_multi/di_prc.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_PRC_H__ +#define __DI_PRC_H__ + +bool dip_prob(void); +void dip_exit(void); + +void dip_even_reg_init_val(unsigned int ch); +void dip_even_unreg_val(unsigned int ch); + +/************************/ +/* CMA */ +/************************/ +void dip_wq_cma_run(unsigned char ch, bool reg_cmd); +bool dip_cma_st_is_ready(unsigned int ch); +bool dip_cma_st_is_idle(unsigned int ch); +bool dip_cma_st_is_idl_all(void); +enum eDI_CMA_ST dip_cma_get_st(unsigned int ch); +void dip_cma_st_set_ready_all(void); +void dip_cma_close(void); +const char *di_cma_dbg_get_st_name(unsigned int ch); + +/*************************/ +/* STATE*/ +/*************************/ +bool dip_event_reg_chst(unsigned int ch); +bool dip_event_unreg_chst(unsigned int ch); +void dip_chst_process_reg(unsigned int ch); + +void dip_hw_process(void); + +void dip_chst_process_ch(void); +bool dip_chst_change_2unreg(void); + +enum eDI_TOP_STATE dip_chst_get(unsigned int ch); +const char *dip_chst_get_name_curr(unsigned int ch); +const char *dip_chst_get_name(enum eDI_TOP_STATE chst); + +/************************************** + * + * summmary variable + * + **************************************/ +void di_sum_reg_init(unsigned int ch); +void di_sum_set(unsigned int ch, enum eDI_SUM id, unsigned int val); +unsigned int di_sum_inc(unsigned int ch, enum eDI_SUM id); +unsigned int di_sum_get(unsigned int ch, enum eDI_SUM id); +void di_sum_get_info(unsigned int ch, enum eDI_SUM id, char **name, + unsigned int *pval); +unsigned int di_sum_get_tab_size(void); +bool di_sum_check(unsigned int ch, enum eDI_SUM id); + +/************************************** + * + * cfg ctr top + * bool + **************************************/ +char *di_cfg_top_get_name(enum eDI_CFG_TOP_IDX idx); +void di_cfg_top_get_info(unsigned int idx, char **name); +void di_cfg_top_init_val(void); +bool di_cfg_top_get(enum eDI_CFG_TOP_IDX id); +void di_cfg_top_set(enum eDI_CFG_TOP_IDX id, bool en); + +/************************************** + * + * cfg ctr x + * bool + **************************************/ +char *di_cfgx_get_name(enum eDI_CFGX_IDX idx); +void di_cfgx_get_info(enum eDI_CFGX_IDX idx, char **name); +void di_cfgx_init_val(void); +bool di_cfgx_get(unsigned int ch, enum eDI_CFGX_IDX idx); +void di_cfgx_set(unsigned int ch, enum eDI_CFGX_IDX idx, bool en); + +/************************************** + * + * module para top + * int + **************************************/ +char *di_mp_uit_get_name(enum eDI_MP_UI_T idx); +void di_mp_uit_init_val(void); +int di_mp_uit_get(enum eDI_MP_UI_T idx); +void di_mp_uit_set(enum eDI_MP_UI_T idx, int val); + +/************************************** + * + * module para x + * unsigned int + **************************************/ +char *di_mp_uix_get_name(enum eDI_MP_UIX_T idx); +void di_mp_uix_init_val(void); +unsigned int di_mp_uix_get(unsigned int ch, enum eDI_MP_UIX_T idx); +void di_mp_uix_set(unsigned int ch, enum eDI_MP_UIX_T idx, + unsigned int val); + +/****************************************/ +/* do_table */ +/****************************************/ +void do_table_init(struct do_table_s *pdo, + const struct do_table_ops_s *ptable, + unsigned int size_tab); +/* now only call in same thread */ +void do_talbe_cmd(struct do_table_s *pdo, enum eDO_TABLE_CMD cmd); +void do_table_working(struct do_table_s *pdo); +bool do_table_is_crr(struct do_table_s *pdo, unsigned int state); + +enum eDI_SUB_ID pw_ch_next_count(enum eDI_SUB_ID channel); + +void dip_init_value_reg(unsigned int ch); + +bool di_is_pause(unsigned int ch); +void di_pause_step_done(unsigned int ch); +void di_pause(unsigned int ch, bool on); + +#endif /*__DI_PRC_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_pre.c b/drivers/amlogic/media/di_multi/di_pre.c new file mode 100644 index 0000000..2c47394 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_pre.c @@ -0,0 +1,985 @@ +/* + * drivers/amlogic/media/di_multi/di_pre.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 "deinterlace.h" +#include "deinterlace_dbg.h" + +#include "di_data_l.h" +#include "di_data.h" +#include "di_dbg.h" +#include "di_vframe.h" +#include "di_que.h" +#include "di_task.h" + +#include "di_prc.h" +#include "di_pre.h" + +#include "nr_downscale.h" +#include "register.h" + +/**************************************** + * 1. copy curr to last + * 2. set curr + ****************************************/ +void pre_vinfo_set(unsigned int ch, + struct vframe_s *ori_vframe) +{ + struct di_hpre_s *pre = get_hw_pre(); + + struct di_vinfo_s *vc = &pre->vinf_curr; + struct di_vinfo_s *vl = &pre->vinf_lst; + + memcpy(vl, vc, sizeof(struct di_vinfo_s)); + + vc->ch = ch; + vc->vtype = ori_vframe->type; + vc->src_type = ori_vframe->source_type; + vc->trans_fmt = ori_vframe->trans_fmt; + + if (COM_ME(ori_vframe->type, VIDTYPE_COMPRESS)) { + vc->h = ori_vframe->compWidth; + vc->v = ori_vframe->compHeight; + } else { + vc->h = ori_vframe->width; + vc->v = ori_vframe->height; + } +} + +/**************************************** + * compare current vframe info with last + * return + * 0. no change + * 1. video format channge + * 2. scan mode channge? + ****************************************/ +unsigned int is_vinfo_change(unsigned int ch) +{ + struct di_hpre_s *pre = get_hw_pre(); + + struct di_vinfo_s *vc = &pre->vinf_curr; + struct di_vinfo_s *vl = &pre->vinf_lst; + struct di_pre_stru_s *ppre = get_pre_stru(ch); + unsigned int ret = 0; + + if (vc->src_type != vl->src_type || + !COM_M(DI_VFM_T_MASK_CHANGE, vc->vtype, vl->vtype) || + vc->v != vl->v || + vc->h != vl->h || + vc->trans_fmt != vl->trans_fmt) { + /* video format changed */ + ret = 1; + } else if (!COM_M(VIDTYPE_VIU_FIELD, vc->vtype, vl->vtype)) + /* just scan mode changed */ + ret = 2; + + if (ret) { + dim_print( + "%s:ch[%d]: %dth source change 2: 0x%x/%d/%d/%d=>0x%x/%d/%d/%d\n", + __func__, + ch, + /*jiffies_to_msecs(jiffies_64),*/ + ppre->in_seq, + vl->vtype, + vl->h, + vl->v, + vl->src_type, + vc->vtype, + vc->h, + vc->v, + vc->src_type); + } + + return ret; +} + +bool dim_bypass_detect(unsigned int ch, struct vframe_s *vfm) +{ + bool ret = false; + + if (!vfm) + return ret; + pre_vinfo_set(ch, vfm); + if (is_vinfo_change(ch)) { + if (!is_bypass2(vfm, ch)) { + set_bypass2_complete(ch, false); + PR_INF("%s:\n", __func__); + /*task_send_ready();*/ + task_send_cmd(LCMD1(eCMD_CHG, ch)); + ret = true; + } + } + return ret; +} + +unsigned int di_get_other_ch(unsigned int curr) +{ + return curr ? 0 : 1; +} + +bool is_bypass_i_p(void) +{ + bool ret = false; + struct di_hpre_s *pre = get_hw_pre(); + struct di_vinfo_s *vc = &pre->vinf_curr; + #if 0 + struct di_vinfo_s *vl = &pre->vinf_lst; + + if (vl->ch != vc->ch && + vf_type_is_interlace(vl->vtype) && + vf_type_is_prog(vc->vtype)) { + ret = true; + } + #else + unsigned int ch_c, ch_l; + + struct di_pre_stru_s *ppre_c, *ppre_l; + + if (!get_reg_flag(0) || + !get_reg_flag(1)) + return ret; + + ch_c = vc->ch; + ch_l = (ch_c ? 0 : 1); + ppre_c = get_pre_stru(ch_c); + ppre_l = get_pre_stru(ch_l); + if (vf_type_is_interlace(ppre_l->cur_inp_type) && + vf_type_is_prog(ppre_c->cur_inp_type)) { + ret = true; + dim_print("ch[%d]:bypass p\n", ch_c); + } + #endif + + return ret; +} + +void dpre_clear(void) +{ + struct di_hpre_s *pre = get_hw_pre(); + + memset(pre, 0, sizeof(struct di_hpre_s)); +} + +void dpre_init(void) +{/*reg:*/ + struct di_hpre_s *pre = get_hw_pre(); + + pre->pre_st = eDI_PRE_ST_IDLE; + + /*timer out*/ + di_tout_int(&pre->tout, 40); /*ms*/ +} + +void pw_use_hw_pre(enum eDI_SUB_ID channel, bool on) +{ + struct di_hpre_s *pre = get_hw_pre(); + + pre->hw_flg_busy_pre = on; + if (on) + pre->curr_ch = channel; +} + +enum eDI_SUB_ID pw_ch_next_count(enum eDI_SUB_ID channel) +{ + int i; + unsigned int lch, nch; + + nch = channel; + for (i = 0; i < DI_CHANNEL_NUB; i++) { + lch = channel + i + 1; + if (lch >= DI_CHANNEL_NUB) + lch -= DI_CHANNEL_NUB; + #if 0 + if (pbm->sub_act_flg[lch]) { + nch = lch; + break; + } + #else + if (get_reg_flag(lch) && + !get_flag_trig_unreg(lch) && + !is_bypss2_complete(lch)) { + nch = lch; + break; + } + #endif + } + return nch; +} + +/****************************************/ +static bool pw_try_sw_ch_next_pre(enum eDI_SUB_ID channel) +{ + bool ret = false; + struct di_hpre_s *pre = get_hw_pre(); + enum eDI_SUB_ID lst_ch, nch; + + lst_ch = channel; + + nch = pw_ch_next_count(lst_ch); + if (!get_reg_flag(nch) || + get_flag_trig_unreg(nch) || + is_bypss2_complete(nch)) + return false; + + pre->curr_ch = nch; + pre->hw_flg_busy_pre = true; + ret = true; + + /*dim_print("%s:%d->%d:%d\n", __func__, lst_ch, nch, ret);*/ + return ret; +} + +/*****************************/ +/* debug */ +/*****************************/ + +unsigned int di_dbg_pre_cnt; + +void dbg_cnt_begin(void) +{ + di_dbg_pre_cnt = 0x10; +} + +void dbg_cnt_print(void) +{ + if (di_dbg_pre_cnt < 0xf) + return; + + if (di_dbg_pre_cnt > 0x10) { + di_dbg_pre_cnt++; + pr_info("di:[%d]\n", di_dbg_pre_cnt); + } + + if (di_dbg_pre_cnt > 0x15) + di_dbg_pre_cnt = 0; +} + +/*****************************/ +/* STEP */ +/*****************************/ +void dpre_recyc(unsigned int ch) +{ + struct di_hpre_s *pre = get_hw_pre(); + + pre->check_recycle_buf_cnt = 0; + while (dim_check_recycle_buf(ch) & 1) { + if (pre->check_recycle_buf_cnt++ > MAX_IN_BUF_NUM) { + di_pr_info("%s: dim_check_recycle_buf time out!!\n", + __func__); + break; + } + } +} + +void dpre_vdoing(unsigned int ch) +{ + struct di_post_stru_s *ppost = get_post_stru(ch); + + ppost->di_post_process_cnt = 0; + while (dim_process_post_vframe(ch)) { + if (ppost->di_post_process_cnt++ > + MAX_POST_BUF_NUM) { + di_pr_info("%s: dim_process_post_vframe time out!!\n", + __func__); + break; + } + } +} + +bool dpre_can_exit(unsigned int ch) +{ + struct di_hpre_s *pre = get_hw_pre(); + bool ret = false; + + if (ch != pre->curr_ch) { + ret = true; + } else { + if (pre->pre_st <= eDI_PRE_ST4_IDLE) + ret = true; + } + pr_info("%s:ch[%d]:curr[%d]:stat[%s] ret[%d]\n", + __func__, + ch, pre->curr_ch, + dpre_state4_name_get(pre->pre_st), + ret); + return ret; +} + +void dpre_dbg_f_trig(unsigned int cmd) +{ + struct di_task *tsk = get_task(); + + struct di_hpre_s *pre = get_hw_pre(); + + if (down_interruptible(&tsk->sem)) { + PR_ERR("%s:can't get sem\n", __func__); + return; + } + + /*set on/off and trig*/ + if (cmd & 0x10) { + pre->dbg_f_en = 1; + pre->dbg_f_cnt = cmd & 0xf; + pre->dbg_f_lstate = pre->pre_st; + } else { + pre->dbg_f_en = 0; + } + + up(&tsk->sem); +} + +void dpre_process(void) +{ + bool reflesh; + struct di_hpre_s *pre = get_hw_pre(); + + if (pre->dbg_f_en) { + if (pre->dbg_f_cnt) { + dpre_process_step4(); + pre->dbg_f_cnt--; + } + if (pre->dbg_f_lstate != pre->pre_st) { + pr_info("ch[%d]:state:%s->%s\n", + pre->curr_ch, + dpre_state4_name_get(pre->dbg_f_lstate), + dpre_state4_name_get(pre->pre_st)); + + pre->dbg_f_lstate = pre->pre_st; + } + return; + } + + reflesh = true; + + while (reflesh) { + reflesh = dpre_process_step4(); + #if 0 /*debug only*/ + dbg_tsk("ch[%d]:st[%s]r[%d]\n", pre->curr_ch, + dpre_state4_name_get(pre->pre_st), reflesh); + #endif + } +} + +enum eDI_PRE_MT { + eDI_PRE_MT_CHECK = K_DO_TABLE_ID_START, + eDI_PRE_MT_SET, + eDI_PRE_MT_WAIT_INT, + eDI_PRE_MT_TIME_OUT, +}; + +/*use do_table:*/ +unsigned int dpre_mtotal_check(void *data) +{ + struct di_hpre_s *pre = get_hw_pre(); + unsigned int ret = K_DO_R_NOT_FINISH; + + 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; + /*dim_print("%s:\n", __func__);*/ + if (dim_pre_de_buf_config(pre->curr_ch)) + ret = K_DO_R_FINISH; + else + ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); + + dim_dbg_pre_cnt(pre->curr_ch, "x"); + } + + return ret; +} + +unsigned int dpre_mtotal_set(void *data) +{ + struct di_hpre_s *pre = get_hw_pre(); + ulong flags = 0; + + /*dim_print("%s:\n", __func__);*/ + spin_lock_irqsave(&plist_lock, flags); + dim_pre_de_process(pre->curr_ch); + spin_unlock_irqrestore(&plist_lock, flags); + /*begin to count timer*/ + di_tout_contr(eDI_TOUT_CONTR_EN, &pre->tout); + + return K_DO_R_FINISH; +} + +enum eDI_WAIT_INT { + eDI_WAIT_INT_NEED_WAIT, + eDI_WAIT_INT_HAVE_INT, + eDI_WAIT_INT_TIME_OUT, +}; + +/* + *return: enum eDI_WAIT_INT + * + */ +enum eDI_WAIT_INT di_pre_wait_int(void *data) +{ + struct di_hpre_s *pre = get_hw_pre(); + ulong flags = 0; + struct di_pre_stru_s *ppre; + + enum eDI_WAIT_INT ret = eDI_WAIT_INT_NEED_WAIT; + + if (pre->flg_int_done) { + /*have INT done flg*/ + /*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 0 + data32 = Rd(DI_INTR_CTRL); + if (((data32 & 0x1) && + ((ppre->enable_mtnwr == 0) || (data32 & 0x2))) || + (ppre->pre_de_clear_flag == 2)) { + dim_RDMA_WR(DI_INTR_CTRL, data32); + } +#endif + di_pre_wait_irq_set(false); + /*finish to count timer*/ + di_tout_contr(eDI_TOUT_CONTR_FINISH, &pre->tout); + spin_lock_irqsave(&plist_lock, flags); + + dim_pre_de_done_buf_config(pre->curr_ch, false); + + pre->flg_int_done = 0; + + dpre_recyc(pre->curr_ch); + dpre_vdoing(pre->curr_ch); + + spin_unlock_irqrestore(&plist_lock, flags); + + ppre = get_pre_stru(pre->curr_ch); +#if 0 + if (ppre->field_count_for_cont == 1) { + usleep_range(2000, 2001); + pr_info("delay 1ms\n"); + } +#endif + + ret = eDI_WAIT_INT_HAVE_INT; + + } else { + /*check if timeout:*/ + if (di_tout_contr(eDI_TOUT_CONTR_CHECK, &pre->tout)) { + di_pre_wait_irq_set(false); + /*return K_DO_R_FINISH;*/ + ret = eDI_WAIT_INT_TIME_OUT; + } + } + /*debug:*/ + if (dbg_first_cnt_pre) + dbg_first_frame("ch[%d],w_int[%d]\n", pre->curr_ch, ret); + + return ret; +} + +unsigned int dpre_mtotal_wait_int(void *data) +{ + enum eDI_WAIT_INT wret; + unsigned int ret = K_DO_R_NOT_FINISH; + + wret = di_pre_wait_int(NULL); + switch (wret) { + case eDI_WAIT_INT_NEED_WAIT: + ret = K_DO_R_NOT_FINISH; + break; + case eDI_WAIT_INT_HAVE_INT: + ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); + break; + case eDI_WAIT_INT_TIME_OUT: + ret = K_DO_R_FINISH; + break; + } + return ret; +} + +void dpre_mtotal_timeout_contr(void) +{ + struct di_hpre_s *pre = get_hw_pre(); + + /*move from di_pre_trigger_work*/ + if (dimp_get(eDI_MP_di_dbg_mask) & 4) + dim_dump_mif_size_state(pre->pres, pre->psts); + + dimh_enable_di_pre_mif(false, dimp_get(eDI_MP_mcpre_en)); + if (di_get_dts_nrds_en()) + dim_nr_ds_hw_ctrl(false); + pre->pres->pre_de_irq_timeout_count++; + + pre->pres->pre_de_busy = 0; + pre->pres->pre_de_clear_flag = 2; + if ((dimp_get(eDI_MP_di_dbg_mask) & 0x2)) { + pr_info("DI:ch[%d]*****wait %d timeout 0x%x(%d ms)*****\n", + pre->curr_ch, + pre->pres->field_count_for_cont, + Rd(DI_INTR_CTRL), + (unsigned int)(cur_to_msecs() - + pre->pres->irq_time[1])); + } + /*******************************/ + dim_pre_de_done_buf_config(pre->curr_ch, true); + + dpre_recyc(pre->curr_ch); + dpre_vdoing(pre->curr_ch); + /*******************************/ + /*dpre_recyc(pre->curr_ch);*/ +} + +unsigned int dpre_mtotal_timeout(void *data) +{ + ulong flags = 0; + + spin_lock_irqsave(&plist_lock, flags); + dpre_mtotal_timeout_contr(); + spin_unlock_irqrestore(&plist_lock, flags); + + return K_DO_R_JUMP(K_DO_TABLE_ID_STOP); +} + +const struct do_table_ops_s pr_mode_total[] = { + /*fix*/ + [K_DO_TABLE_ID_PAUSE] = { + .id = K_DO_TABLE_ID_PAUSE, + .mark = 0, + .con = NULL, + .do_op = NULL, + .do_stop_op = NULL, + .name = "pause", + }, + [K_DO_TABLE_ID_STOP] = { + .id = K_DO_TABLE_ID_STOP, + .mark = 0, + .con = NULL, + .do_op = NULL, + .do_stop_op = NULL, + .name = "stop", + }, + /******************/ + [K_DO_TABLE_ID_START] = { /*eDI_PRE_MT_CHECK*/ + .id = K_DO_TABLE_ID_START, + .mark = 0, + .con = NULL, + .do_op = dpre_mtotal_check, + .do_stop_op = NULL, + .name = "start-check", + }, + [eDI_PRE_MT_SET] = { + .id = eDI_PRE_MT_SET, + .mark = 0, + .con = NULL, + .do_op = dpre_mtotal_set, + .do_stop_op = NULL, + .name = "set", + }, + [eDI_PRE_MT_WAIT_INT] = { + .id = eDI_PRE_MT_WAIT_INT, + .mark = 0, + .con = NULL, + .do_op = dpre_mtotal_wait_int, + .do_stop_op = NULL, + .name = "wait_int", + }, + [eDI_PRE_MT_TIME_OUT] = { + .id = eDI_PRE_MT_TIME_OUT, + .mark = 0, + .con = NULL, + .do_op = dpre_mtotal_timeout, + .do_stop_op = NULL, + .name = "timeout", + }, +}; + +/**************************** + * + * mode for p + * + ****************************/ +enum eDI_PRE_MP { + eDI_PRE_MP_CHECK = K_DO_TABLE_ID_START, + eDI_PRE_MP_SET, + eDI_PRE_MP_WAIT_INT, + eDI_PRE_MP_TIME_OUT, + eDI_PRE_MP_CHECK2, + eDI_PRE_MP_SET2, + eDI_PRE_MP_WAIT_INT2, + eDI_PRE_MP_TIME_OUT2, +}; + +unsigned int dpre_mp_check(void *data) +{ + struct di_hpre_s *pre = get_hw_pre(); + unsigned int ret = K_DO_R_NOT_FINISH; + + 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; + /*dim_print("%s:\n", __func__);*/ + if (dim_pre_de_buf_config(pre->curr_ch)) { + /*pre->flg_wait_int = false;*/ + /*pre_p_asi_set_next(pre->curr_ch);*/ + ret = K_DO_R_FINISH; + } else { + /*pre->flg_wait_int = false;*/ + ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); + } + dim_dbg_pre_cnt(pre->curr_ch, "x"); + } + + return ret; +} + +unsigned int dpre_mp_check2(void *data) +{ + struct di_hpre_s *pre = get_hw_pre(); + unsigned int ret = K_DO_R_NOT_FINISH; + + if (dim_pre_de_buf_config(pre->curr_ch)) { + /*pre->flg_wait_int = false;*/ + ret = K_DO_R_FINISH; + } + #if 0 + else { + PR_ERR("%s:not second?ch[%d]\n", __func__, pre->curr_ch); + ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); + } + #endif + + return ret; +} + +unsigned int dpre_mp_wait_int(void *data) +{ + enum eDI_WAIT_INT wret; + unsigned int ret = K_DO_R_NOT_FINISH; + + wret = di_pre_wait_int(NULL); + switch (wret) { + case eDI_WAIT_INT_NEED_WAIT: + ret = K_DO_R_NOT_FINISH; + break; + case eDI_WAIT_INT_HAVE_INT: + ret = K_DO_R_JUMP(eDI_PRE_MP_CHECK2); + break; + case eDI_WAIT_INT_TIME_OUT: + ret = K_DO_R_FINISH; + break; + } + return ret; +} + +unsigned int dpre_mp_wait_int2(void *data) +{ + enum eDI_WAIT_INT wret; + unsigned int ret = K_DO_R_NOT_FINISH; + + wret = di_pre_wait_int(NULL); + switch (wret) { + case eDI_WAIT_INT_NEED_WAIT: + ret = K_DO_R_NOT_FINISH; + break; + case eDI_WAIT_INT_HAVE_INT: + ret = K_DO_R_JUMP(K_DO_TABLE_ID_STOP); + break; + case eDI_WAIT_INT_TIME_OUT: + ret = K_DO_R_FINISH; + break; + } + return ret; +} + +unsigned int dpre_mp_timeout(void *data) +{ + dpre_mtotal_timeout_contr(); + + return K_DO_R_FINISH; +} + +unsigned int dpre_mp_timeout2(void *data) +{ + dpre_mtotal_timeout_contr(); + + return K_DO_R_JUMP(K_DO_TABLE_ID_STOP); +} + +const struct do_table_ops_s pre_mode_proc[] = { + /*fix*/ + [K_DO_TABLE_ID_PAUSE] = { + .id = K_DO_TABLE_ID_PAUSE, + .mark = 0, + .con = NULL, + .do_op = NULL, + .do_stop_op = NULL, + .name = "pause", + }, + [K_DO_TABLE_ID_STOP] = { + .id = K_DO_TABLE_ID_STOP, + .mark = 0, /*stop / pause*/ + .con = NULL, + .do_op = NULL, + .do_stop_op = NULL, + .name = "stop", + }, + /******************/ + [K_DO_TABLE_ID_START] = { /*eDI_PRE_MP_CHECK*/ + .id = K_DO_TABLE_ID_START, + .mark = 0, /*stop / pause*/ + .con = NULL, + .do_op = dpre_mp_check, + .do_stop_op = NULL, + .name = "start-check", + }, + [eDI_PRE_MP_SET] = { + .id = eDI_PRE_MP_SET, + .mark = 0, /*stop / pause*/ + .con = NULL, /*condition*/ + .do_op = dpre_mtotal_set, + .do_stop_op = NULL, + .name = "pset", + }, + [eDI_PRE_MP_WAIT_INT] = { + .id = eDI_PRE_MP_WAIT_INT, + .mark = 0, /*stop / pause*/ + .con = NULL, /*condition*/ + .do_op = dpre_mp_wait_int, + .do_stop_op = NULL, + .name = "pwait_int", + }, + [eDI_PRE_MP_TIME_OUT] = { + .id = eDI_PRE_MP_TIME_OUT, + .mark = 0, /*stop / pause*/ + .con = NULL, /*condition*/ + .do_op = dpre_mp_timeout, + .do_stop_op = NULL, + .name = "ptimeout", + }, + /******/ + [eDI_PRE_MP_CHECK2] = { /*eDI_PRE_MP_CHECK2*/ + .id = eDI_PRE_MP_CHECK2, + .mark = 0, /*stop / pause*/ + .con = NULL, /*condition*/ + .do_op = dpre_mp_check2, + .do_stop_op = NULL, + .name = "start-check", + }, + [eDI_PRE_MP_SET2] = { + .id = eDI_PRE_MP_SET2, + .mark = 0, /*stop / pause*/ + .con = NULL, /*condition*/ + .do_op = dpre_mtotal_set, + .do_stop_op = NULL, + .name = "psetp2", + }, + [eDI_PRE_MP_WAIT_INT2] = { + .id = eDI_PRE_MP_WAIT_INT2, + .mark = 0, /*stop / pause*/ + .con = NULL, /*condition*/ + .do_op = dpre_mp_wait_int2, + .do_stop_op = NULL, + .name = "pwait_int2", + }, + [eDI_PRE_MP_TIME_OUT2] = { + .id = eDI_PRE_MP_TIME_OUT2, + .mark = 0, /*stop / pause*/ + .con = NULL, /*condition*/ + .do_op = dpre_mp_timeout2, + .do_stop_op = NULL, + .name = "ptimeout2", + }, + +}; + +void pre_mode_setting(void) +{ + struct di_hpre_s *pre = get_hw_pre(); + + if (pre->pre_st != eDI_PRE_ST4_DO_TABLE) + return; + + do_table_working(&pre->sdt_mode); +} + +/*--------------------------*/ +enum eDI_WORK_MODE pre_cfg_count_mode(unsigned int ch, struct vframe_s *vframe) +{ + enum eDI_WORK_MODE pmode; + + if (is_bypass2(vframe, ch)) { + pmode = eDI_WORK_MODE_bypass_all; + return pmode; + } + + if (COM_ME(vframe->type, VIDTYPE_INTERLACE)) { + /*interlace:*/ + pmode = eDI_WORK_MODE_i; + return pmode; + } + + if (dimp_get(eDI_MP_prog_proc_config) & 0x10) + pmode = eDI_WORK_MODE_p_as_p; + else if (is_from_vdin(vframe)) + pmode = eDI_WORK_MODE_p_use_ibuf; + else + pmode = eDI_WORK_MODE_p_as_i; + + return pmode; +} + +unsigned int dpre_check_mode(unsigned int ch) +{ + struct vframe_s *vframe; + unsigned int mode; + + vframe = pw_vf_peek(ch); + + if (!vframe) + return eDI_WORK_MODE_NONE; + mode = pre_cfg_count_mode(ch, vframe);/*eDI_WORK_MODE_all;*/ + + return mode; +} + +/*--------------------------*/ +bool dpre_step4_idle(void) +{ + struct di_hpre_s *pre = get_hw_pre(); + bool reflesh = false; + unsigned int ch; + + ch = pre->curr_ch; + if (!pw_try_sw_ch_next_pre(ch)) + return false; + + if (pre->idle_cnt >= DI_CHANNEL_NUB) { + pre->idle_cnt = 0; + return false; + } + pre->pres = get_pre_stru(pre->curr_ch); + pre->psts = get_post_stru(pre->curr_ch); + + /*state*/ + pre->pre_st++;/*tmp*/ + reflesh = true; + + return reflesh; +} + +bool dpre_step4_check(void) +{ + struct di_hpre_s *pre = get_hw_pre(); + bool reflesh = false; + unsigned int mode; + + /*get vframe and select mode + * now: fix use total table + */ + + mode = dpre_check_mode(pre->curr_ch); + + if (mode == eDI_WORK_MODE_NONE) { + pre->pre_st--; + pre->idle_cnt++; + return true; + } + pre->idle_cnt = 0; + if (mode == eDI_WORK_MODE_p_as_i) { + do_table_init(&pre->sdt_mode, + &pre_mode_proc[0], + ARRAY_SIZE(pre_mode_proc)); + + } else { + do_table_init(&pre->sdt_mode, + &pr_mode_total[0], + ARRAY_SIZE(pr_mode_total)); + } + do_talbe_cmd(&pre->sdt_mode, eDO_TABLE_CMD_START); + + /*state*/ + pre->pre_st++; + reflesh = true; + + return reflesh; +} + +bool dpre_step4_do_table(void) +{ + struct di_hpre_s *pre = get_hw_pre(); + bool reflesh = false; + + if (do_table_is_crr(&pre->sdt_mode, K_DO_TABLE_ID_STOP)) { + pre->pre_st = eDI_PRE_ST4_IDLE; + reflesh = true; + } + return reflesh; +} + +const struct di_func_tab_s di_pre_func_tab4[] = { + {eDI_PRE_ST4_EXIT, NULL}, + {eDI_PRE_ST4_IDLE, dpre_step4_idle}, + {eDI_PRE_ST4_CHECK, dpre_step4_check}, + {eDI_PRE_ST4_DO_TABLE, dpre_step4_do_table}, +}; + +const char * const dpre_state_name4[] = { + "EXIT", + "IDLE", /*swith to next channel?*/ + "CHECK", + "DO_TABLE", +}; + +const char *dpre_state4_name_get(enum eDI_PRE_ST4 state) +{ + if (state > eDI_PRE_ST4_DO_TABLE) + return "nothing"; + + return dpre_state_name4[state]; +} + +bool dpre_process_step4(void) +{ + struct di_hpre_s *pre = get_hw_pre(); + enum eDI_PRE_ST4 pre_st = pre->pre_st; + ulong flags = 0; + + if (pre_st > eDI_PRE_ST4_EXIT) { + spin_lock_irqsave(&plist_lock, flags); + dim_recycle_post_back(pre->curr_ch); + dpre_recyc(pre->curr_ch); + dpre_vdoing(pre->curr_ch); + spin_unlock_irqrestore(&plist_lock, flags); + } + if ((pre_st <= eDI_PRE_ST4_DO_TABLE) && + di_pre_func_tab4[pre_st].func) { + return di_pre_func_tab4[pre_st].func(); + } + + return false; +} diff --git a/drivers/amlogic/media/di_multi/di_pre.h b/drivers/amlogic/media/di_multi/di_pre.h new file mode 100644 index 0000000..2f46b12 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_pre.h @@ -0,0 +1,38 @@ +/* + * drivers/amlogic/media/di_multi/di_pre.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_PRE_H__ +#define __DI_PRE_H__ + +void dpre_process(void); + +void dpre_init(void); + +const char *dpre_state_name_get(enum eDI_PRE_ST state); +void dpre_dbg_f_trig(unsigned int cmd); +void pre_vinfo_set(unsigned int ch, + struct vframe_s *ori_vframe); +unsigned int is_vinfo_change(unsigned int ch); +bool dpre_can_exit(unsigned int ch); +bool is_bypass_i_p(void); +bool dim_bypass_detect(unsigned int ch, struct vframe_s *vfm); + +void pre_mode_setting(void); +bool dpre_process_step4(void); +const char *dpre_state4_name_get(enum eDI_PRE_ST4 state); + +#endif /*__DI_PRE_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_que.c b/drivers/amlogic/media/di_multi/di_que.c new file mode 100644 index 0000000..1d96da9 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_que.c @@ -0,0 +1,995 @@ +/* + * drivers/amlogic/media/di_multi/di_que.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 "deinterlace.h" + +#include "di_data_l.h" +#include "di_que.h" +#include "di_vframe.h" + +#include "di_prc.h" + +const char * const di_name_new_que[QUE_NUB] = { + "QUE_IN_FREE", /*0*/ + "QUE_PRE_READY", /*1*/ + "QUE_POST_FREE", /*2*/ + "QUE_POST_READY", /*3*/ + "QUE_POST_BACK", /*4*/ + "QUE_DBG", +/* "QUE_NUB",*/ + +}; + +#define que_dbg dim_print + +static void pw_queue_clear(unsigned int ch, enum QUE_TYPE qtype) +{ + struct di_ch_s *pch = get_chdata(ch); + +#if 0 + if (qtype >= QUE_NUB) + return; +#endif + kfifo_reset(&pch->fifo[qtype]); +} + +bool pw_queue_in(unsigned int ch, enum QUE_TYPE qtype, unsigned int buf_index) +{ + struct di_ch_s *pch = get_chdata(ch); + +#if 0 + if (qtype >= QUE_NUB) + return false; +#endif + if (kfifo_in(&pch->fifo[qtype], &buf_index, sizeof(unsigned int)) + != sizeof(unsigned int)) + return false; +#if 0 + + /*below for debug: save in que*/ + if (qtype <= QUE_POST_RECYC) { + if (buf_index >= MAX_POST_BUF_NUM) { + pr_err("%s:err:overflow?[%d]\n", __func__, buf_index); + } else { + ppw = &pch->lpost_buf[buf_index]; + ppw->in_qtype = qtype; + } + } +#endif + return true; +} + +bool pw_queue_out(unsigned int ch, enum QUE_TYPE qtype, + unsigned int *buf_index) +{ + struct di_ch_s *pch = get_chdata(ch); + unsigned int index; + +#if 0 + if (qtype >= QUE_NUB) + return false; +#endif + if (kfifo_out(&pch->fifo[qtype], &index, sizeof(unsigned int)) + != sizeof(unsigned int)) + return false; + + *buf_index = index; + + return true; +} + +static bool pw_queue_peek(unsigned int ch, enum QUE_TYPE qtype, + unsigned int *buf_index) +{ + struct di_ch_s *pch = get_chdata(ch); + unsigned int index; + +#if 0 + if (qtype >= QUE_NUB) + return false; +#endif + + if (kfifo_out_peek(&pch->fifo[qtype], &index, sizeof(unsigned int)) + != sizeof(unsigned int)) + return false; + + *buf_index = index; + + return true; +} + +bool pw_queue_move(unsigned int ch, enum QUE_TYPE qtypef, enum QUE_TYPE qtypet, + unsigned int *oindex) +{ + struct di_ch_s *pch = get_chdata(ch); + unsigned int index; + + /*struct di_post_buf_s *ppw;*/ /*debug only*/ + +#if 0 + if (qtypef >= QUE_NUB || qtypet >= QUE_NUB) + return false; +#endif + if (kfifo_out(&pch->fifo[qtypef], &index, sizeof(unsigned int)) + != sizeof(unsigned int)) { + PR_ERR("qtypef[%d] is empty\n", qtypef); + return false; + } + if (kfifo_in(&pch->fifo[qtypet], &index, sizeof(unsigned int)) + != sizeof(unsigned int)) { + PR_ERR("qtypet[%d] is full\n", qtypet); + return false; + } + + *oindex = index; +#if 0 + if (qtypet <= QUE_POST_RECYC) { + /*below for debug: save in que*/ + if (index >= MAX_POST_BUF_NUM) { + pr_err("%s:err:overflow?[%d]\n", __func__, index); + } else { + ppw = &pch->lpost_buf[index]; + ppw->in_qtype = qtypet; + } + } +#endif + return true; +} + +bool pw_queue_empty(unsigned int ch, enum QUE_TYPE qtype) +{ + struct di_ch_s *pch = get_chdata(ch); + + if (kfifo_is_empty(&pch->fifo[qtype])) + return true; + + return false; +} + +int di_que_list_count(unsigned int ch, enum QUE_TYPE qtype) +{ + struct di_ch_s *pch = get_chdata(ch); + unsigned int length; + +#if 0 + if (qtype >= QUE_NUB) + return -1; +#endif + length = kfifo_len(&pch->fifo[qtype]); + length = length / sizeof(unsigned int); + + return length; +} + +/***************************************/ +/*outbuf : array size MAX_FIFO_SIZE*/ +/***************************************/ +bool di_que_list(unsigned int ch, enum QUE_TYPE qtype, unsigned int *outbuf, + unsigned int *rsize) +{ + struct di_ch_s *pch = get_chdata(ch); +/* unsigned int tmp[MAX_FIFO_SIZE + 1];*/ + int i; + unsigned int index; + bool ret = false; + + /*que_dbg("%s:begin\n", __func__);*/ + for (i = 0; i < MAX_FIFO_SIZE; i++) + outbuf[i] = 0xff; + + if (kfifo_is_empty(&pch->fifo[qtype])) { + que_dbg("\t%d:empty\n", qtype); + *rsize = 0; + return true; + } + + ret = true; + memcpy(&pch->fifo[QUE_DBG], &pch->fifo[qtype], + sizeof(pch->fifo[qtype])); + +#if 0 + if (kfifo_is_empty(&pbm->fifo[QUE_DBG])) + pr_err("%s:err, kfifo can not copy?\n", __func__); + +#endif + i = 0; + *rsize = 0; + + while (kfifo_out(&pch->fifo[QUE_DBG], &index, sizeof(unsigned int)) + == sizeof(unsigned int)) { + outbuf[i] = index; + /*pr_info("%d->%d\n",i,index);*/ + i++; + } + *rsize = di_que_list_count(ch, qtype); + #if 0 /*debug only*/ + que_dbg("%s: size[%d]\n", di_name_new_que[qtype], *rsize); + for (i = 0; i < *rsize; i++) + que_dbg("%d,", outbuf[i]); + + que_dbg("\n"); + #endif + /*que_dbg("finish\n");*/ + + return ret; +} + +int di_que_is_empty(unsigned int ch, enum QUE_TYPE qtype) +{ + struct di_ch_s *pch = get_chdata(ch); + +#if 0 + if (qtype >= QUE_NUB) + return -1; +#endif + return kfifo_is_empty(&pch->fifo[qtype]); +} + +void di_que_init(unsigned int ch) +{ + int i; + + for (i = 0; i < QUE_NUB; i++) + pw_queue_clear(ch, i); +} + +bool di_que_alloc(unsigned int ch) +{ + int i; + int ret; + bool flg_err; + struct di_ch_s *pch = get_chdata(ch); + + /*kfifo----------------------------*/ + flg_err = 0; + for (i = 0; i < QUE_NUB; i++) { + ret = kfifo_alloc(&pch->fifo[i], + sizeof(unsigned int) * MAX_FIFO_SIZE, + GFP_KERNEL); + if (ret < 0) { + flg_err = 1; + PR_ERR("%s:%d:can't get kfifo\n", __func__, i); + break; + } + pch->flg_fifo[i] = 1; + } +#if 0 + /*canvas-----------------------------*/ + canvas_alloc(); +#endif +/* pdp_clear();*/ + + if (!flg_err) { + /*pbm->flg_fifo = 1;*/ + pr_info("%s:ok\n", __func__); + ret = true; + } else { + di_que_release(ch); + ret = false; + } + + return ret; +} + +void di_que_release(unsigned int ch) +{ + struct di_ch_s *pch = get_chdata(ch); + int i; + +/* canvas_release();*/ + for (i = 0; i < QUE_NUB; i++) { + if (pch->flg_fifo[i]) { + kfifo_free(&pch->fifo[i]); + pch->flg_fifo[i] = 0; + } + } + + pr_info("%s:ok\n", __func__); +} + +/******************************************** + *get di_buf from index that same in que + * (di_buf->type << 8) | (di_buf->index) + ********************************************/ +struct di_buf_s *pw_qindex_2_buf(unsigned int ch, unsigned int qindex) +{ + union uDI_QBUF_INDEX index; + struct di_buf_s *di_buf; + struct di_buf_pool_s *pbuf_pool = get_buf_pool(ch); + + index.d32 = qindex; + di_buf = &pbuf_pool[index.b.type - 1].di_buf_ptr[index.b.index]; + + return di_buf; +} + +/********************************************/ +/*get di_buf from index that same in que*/ +/*(di_buf->type << 8) | (di_buf->index)*/ +/********************************************/ +static unsigned int pw_buf_2_qindex(unsigned int ch, struct di_buf_s *pdi_buf) +{ + union uDI_QBUF_INDEX index; + + index.b.index = pdi_buf->index; + index.b.type = pdi_buf->type; + return index.d32; +} + +/*di_buf is out*/ +struct di_buf_s *di_que_out_to_di_buf(unsigned int ch, enum QUE_TYPE qtype) +{ + unsigned int q_index; + struct di_buf_s *pdi_buf = NULL; + + if (!pw_queue_peek(ch, qtype, &q_index)) + return pdi_buf; + + pdi_buf = pw_qindex_2_buf(ch, q_index); + if (!pdi_buf) { + PR_ERR("di:err:%s:buf is null[%d]\n", __func__, q_index); + return NULL; + } + + pw_queue_out(ch, qtype, &q_index); + pdi_buf->queue_index = -1; + + return pdi_buf; +} + +/*di_buf is input*/ +bool di_que_out(unsigned int ch, enum QUE_TYPE qtype, struct di_buf_s *di_buf) +{ + unsigned int q_index; + unsigned int q_index2; + + if (!pw_queue_peek(ch, qtype, &q_index)) + return false; + + q_index2 = pw_buf_2_qindex(ch, di_buf); + if (q_index2 != q_index) { + PR_ERR("di:%s:not map[%d,%d]\n", __func__, q_index2, q_index); + return false; + } + + pw_queue_out(ch, qtype, &q_index); + di_buf->queue_index = -1; + return true; +} + +bool di_que_in(unsigned int ch, enum QUE_TYPE qtype, struct di_buf_s *di_buf) +{ + unsigned int q_index; + + if (!di_buf) { + PR_ERR("di:%s:err:di_buf is NULL,ch[%d],qtype[%d]\n", + __func__, ch, qtype); + return false; + } + if (di_buf->queue_index != -1) { + PR_ERR("di:%s:buf in some que,ch[%d],qt[%d],qi[%d],bi[%d]\n", + __func__, + ch, qtype, di_buf->queue_index, di_buf->index); + return false; + } + + q_index = pw_buf_2_qindex(ch, di_buf); + + if (!pw_queue_in(ch, qtype, q_index)) { + PR_ERR("di:%s:err:can't que in,ch[%d],qtype[%d],q_index[%d]\n", + __func__, + ch, qtype, q_index); + return false; + } + di_buf->queue_index = qtype + QUEUE_NUM; + + if (qtype == QUE_PRE_READY) + dim_print("di:pre_ready in %d\n", di_buf->index); + + return true; +} + +bool di_que_is_in_que(unsigned int ch, enum QUE_TYPE qtype, + struct di_buf_s *di_buf) +{ + unsigned int q_index; + unsigned int arr[MAX_FIFO_SIZE + 1]; + unsigned int asize = 0; + bool ret = false; + unsigned int i; + + if (!di_buf) + return false; + + q_index = pw_buf_2_qindex(ch, di_buf); + + di_que_list(ch, qtype, &arr[0], &asize); + + if (asize == 0) + return ret; + + for (i = 0; i < asize; i++) { + if (arr[i] == q_index) { + ret = true; + break; + } + } + return ret; +} + +/*same as get_di_buf_head*/ +struct di_buf_s *di_que_peek(unsigned int ch, enum QUE_TYPE qtype) +{ + struct di_buf_s *di_buf = NULL; + unsigned int q_index; + + if (!pw_queue_peek(ch, qtype, &q_index)) + return di_buf; + di_buf = pw_qindex_2_buf(ch, q_index); + + return di_buf; +} + +bool di_que_type_2_new(unsigned int q_type, enum QUE_TYPE *nqtype) +{ + if (!F_IN(q_type, QUEUE_NEW_THD_MIN, QUEUE_NEW_THD_MAX)) + return false; + *nqtype = (enum QUE_TYPE)(q_type - QUEUE_NUM); + + return true; +} + +/**********************************************************/ +/**********************************************************/ +/*ary add this function for reg ini value, no need wait peek*/ +void queue_init2(unsigned int channel) +{ + int i, j; + struct queue_s *pqueue = get_queue(channel); + + for (i = 0; i < QUEUE_NUM; i++) { + queue_t *q = &pqueue[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 0 + if ((i == QUEUE_LOCAL_FREE) && dim_get_use_2_int_buf()) + q->type = 2; +#endif + } +} + +void queue_init(unsigned int channel, int local_buffer_num) +{ + int i, j; + struct di_buf_s *pbuf_local = get_buf_local(channel); + struct di_buf_s *pbuf_in = get_buf_in(channel); + struct di_buf_s *pbuf_post = get_buf_post(channel); + struct queue_s *pqueue = get_queue(channel); + struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel); + + for (i = 0; i < QUEUE_NUM; i++) { + queue_t *q = &pqueue[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) && + dimp_get(eDI_MP_use_2_interlace_buff)) + q->type = 2; + } + if (local_buffer_num > 0) { + pbuf_pool[VFRAME_TYPE_IN - 1].di_buf_ptr = &pbuf_in[0]; + pbuf_pool[VFRAME_TYPE_IN - 1].size = MAX_IN_BUF_NUM; + + pbuf_pool[VFRAME_TYPE_LOCAL - 1].di_buf_ptr = &pbuf_local[0]; + pbuf_pool[VFRAME_TYPE_LOCAL - 1].size = local_buffer_num; + + pbuf_pool[VFRAME_TYPE_POST - 1].di_buf_ptr = &pbuf_post[0]; + pbuf_pool[VFRAME_TYPE_POST - 1].size = MAX_POST_BUF_NUM; + } +} + +struct di_buf_s *get_di_buf_head(unsigned int channel, int queue_idx) +{ + struct queue_s *pqueue = get_queue(channel); + queue_t *q = &pqueue[queue_idx]; + int idx; + unsigned int pool_idx, di_buf_idx; + struct di_buf_s *di_buf = NULL; + struct di_buf_pool_s *pbuf_pool = get_buf_pool(channel); + enum QUE_TYPE nqtype;/*new que*/ + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) + dim_print("%s:<%d:%d,%d,%d>\n", __func__, queue_idx, + q->num, q->in_idx, q->out_idx); + /* ****new que***** */ + if (di_que_type_2_new(queue_idx, &nqtype)) + return di_que_peek(channel, nqtype); + + /* **************** */ + + 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 < pbuf_pool[pool_idx].size) + di_buf = &pbuf_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 (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(2); + dim_vcry_set_log_q_idx(queue_idx); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + di_buf = NULL; + } + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) { + if (di_buf) + dim_print("%s: %x(%d,%d)\n", __func__, di_buf, + pool_idx, di_buf_idx); + else + dim_print("%s: %x\n", __func__, di_buf); + } + + return di_buf; +} + +/*ary: note:*/ +/*a. di_buf->queue_index = -1*/ +/*b. */ +void queue_out(unsigned int channel, struct di_buf_s *di_buf) +{ + int i; + queue_t *q; + struct queue_s *pqueue = get_queue(channel); + enum QUE_TYPE nqtype;/*new que*/ + + if (!di_buf) { + PR_ERR("%s:Error\n", __func__); + + if (dim_vcry_get_flg() == 0) + dim_vcry_set_log_reason(3); + + dim_vcry_flg_inc(); + return; + } + /* ****new que***** */ + if (di_que_type_2_new(di_buf->queue_index, &nqtype)) { + di_que_out(channel, nqtype, di_buf); /*?*/ + return; + } + /* **************** */ + + if (di_buf->queue_index >= 0 && di_buf->queue_index < QUEUE_NUM) { + q = &pqueue[di_buf->queue_index]; + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) + dim_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_ERR( + "%s: Error (%d, %x,%x)\n", + __func__, + di_buf->queue_index, + q->pool[q->out_idx], + ((di_buf->type << 8) | + (di_buf->index))); + + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(4); + dim_vcry_set_log_q_idx(di_buf->queue_index); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + } + } 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_ERR("%s: Error\n", __func__); + + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(5); + dim_vcry_set_log_q_idx(di_buf->queue_index); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + } + } 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_ERR("%s: Error\n", __func__); + + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(5); + dim_vcry_set_log_q_idx(di_buf->queue_index); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + } + } + } + } else { + PR_ERR("%s: Error, queue_index %d is not right\n", + __func__, di_buf->queue_index); + + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(6); + dim_vcry_set_log_q_idx(0); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + } + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) + dim_print("%s done\n", __func__); +} + +void queue_out_dbg(unsigned int channel, struct di_buf_s *di_buf) +{ + int i; + queue_t *q; + struct queue_s *pqueue = get_queue(channel); + enum QUE_TYPE nqtype;/*new que*/ + + if (!di_buf) { + PR_ERR("%s:Error\n", __func__); + + if (dim_vcry_get_flg() == 0) + dim_vcry_set_log_reason(3); + + dim_vcry_flg_inc(); + return; + } + /* ****new que***** */ + if (di_que_type_2_new(di_buf->queue_index, &nqtype)) { + di_que_out(channel, nqtype, di_buf); /*?*/ + pr_info("dbg1:nqtype=%d\n", nqtype); + return; + } + /* **************** */ + + if (di_buf->queue_index >= 0 && di_buf->queue_index < QUEUE_NUM) { + q = &pqueue[di_buf->queue_index]; + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) + dim_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) { + pr_info("dbg3\n"); + 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_ERR( + "%s: Error (%d, %x,%x)\n", + __func__, + di_buf->queue_index, + q->pool[q->out_idx], + ((di_buf->type << 8) | + (di_buf->index))); + + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(4); + dim_vcry_set_log_q_idx(di_buf->queue_index); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + } + } 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; + } + } + pr_info("dbg2:i=%d,qindex=%d\n", i, + di_buf->queue_index); + if (i == MAX_QUEUE_POOL_SIZE) { + PR_ERR("%s: Error\n", __func__); + + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(5); + dim_vcry_set_log_q_idx(di_buf->queue_index); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + } + } else if (q->type == 2) { + int pool_val = + (di_buf->type << 8) | (di_buf->index); + + pr_info("dbg4\n"); + 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_ERR("%s: Error\n", __func__); + + if (dim_vcry_get_flg() == 0) { + dim_vcry_set(5, + di_buf->queue_index, + di_buf); + } + dim_vcry_flg_inc(); + } + } + } + } else { + PR_ERR("%s: Error, queue_index %d is not right\n", + __func__, di_buf->queue_index); + + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(6); + dim_vcry_set_log_q_idx(0); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + } + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) + dim_print("%s done\n", __func__); +} + +/***************************************/ +/* set di_buf->queue_index*/ +/***************************************/ +void queue_in(unsigned int channel, struct di_buf_s *di_buf, int queue_idx) +{ + queue_t *q = NULL; + struct queue_s *pqueue = get_queue(channel); + enum QUE_TYPE nqtype;/*new que*/ + + if (!di_buf) { + PR_ERR("%s:Error\n", __func__); + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(7); + dim_vcry_set_log_q_idx(queue_idx); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + return; + } + /* ****new que***** */ + if (di_que_type_2_new(queue_idx, &nqtype)) { + di_que_in(channel, nqtype, di_buf); + return; + } + /* **************** */ + if (di_buf->queue_index != -1) { + PR_ERR("%s:%s[%d] queue_index(%d) is not -1, to que[%d]\n", + __func__, dim_get_vfm_type_name(di_buf->type), + di_buf->index, di_buf->queue_index, queue_idx); + if (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(8); + dim_vcry_set_log_q_idx(queue_idx); + dim_vcry_set_log_di_buf(di_buf); + } + dim_vcry_flg_inc(); + return; + } + q = &pqueue[queue_idx]; + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) + dim_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 (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(9); + dim_vcry_set_log_q_idx(queue_idx); + } + dim_vcry_flg_inc(); + } + } 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 (dim_vcry_get_flg() == 0) { + dim_vcry_set_log_reason(9); + dim_vcry_set_log_q_idx(queue_idx); + } + dim_vcry_flg_inc(); + } + } + + if (dimp_get(eDI_MP_di_log_flag) & DI_LOG_QUEUE) + dim_print("%s done\n", __func__); +} + +int list_count(unsigned int channel, int queue_idx) +{ + struct queue_s *pqueue; + enum QUE_TYPE nqtype;/*new que*/ + + /* ****new que***** */ + if (di_que_type_2_new(queue_idx, &nqtype)) { + PR_ERR("%s:err: over flow\n", __func__); + return di_que_list_count(channel, nqtype); + } + /* **************** */ + + pqueue = get_queue(channel); + return pqueue[queue_idx].num; +} + +bool queue_empty(unsigned int channel, int queue_idx) +{ + struct queue_s *pqueue; + bool ret; + enum QUE_TYPE nqtype;/*new que*/ + + /* ****new que***** */ + if (di_que_type_2_new(queue_idx, &nqtype)) { + PR_ERR("%s:err: over flow\n", __func__); + return di_que_is_empty(channel, nqtype); + } + /* **************** */ + + pqueue = get_queue(channel); + ret = (pqueue[queue_idx].num == 0); + + return ret; +} + +bool is_in_queue(unsigned int channel, struct di_buf_s *di_buf, int queue_idx) +{ + bool ret = 0; + struct di_buf_s *p = NULL; + int itmp; + unsigned int overflow_cnt; + enum QUE_TYPE nqtype;/*new que*/ + + /* ****new que***** */ + if (di_que_type_2_new(queue_idx, &nqtype)) + return di_que_is_in_que(channel, nqtype, di_buf); + + /* **************** */ + + overflow_cnt = 0; + if (!di_buf || (queue_idx < 0) || (queue_idx >= QUEUE_NUM)) { + ret = 0; + dim_print("%s: not in queue:%d!!!\n", __func__, queue_idx); + return ret; + } + queue_for_each_entry(p, channel, queue_idx, list) { + if (p == di_buf) { + ret = 1; + break; + } + if (overflow_cnt++ > MAX_QUEUE_POOL_SIZE) { + ret = 0; + dim_print("%s: overflow_cnt!!!\n", __func__); + break; + } + } + return ret; +} + diff --git a/drivers/amlogic/media/di_multi/di_que.h b/drivers/amlogic/media/di_multi/di_que.h new file mode 100644 index 0000000..f2f35ab --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_que.h @@ -0,0 +1,76 @@ +/* + * drivers/amlogic/media/di_multi/di_que.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_QUE_H__ +#define __DI_QUE_H__ + +void queue_init(unsigned int channel, int local_buffer_num); +void queue_out(unsigned int channel, struct di_buf_s *di_buf); +void queue_in(unsigned int channel, struct di_buf_s *di_buf, + int queue_idx); +int list_count(unsigned int channel, int queue_idx); +bool queue_empty(unsigned int channel, int queue_idx); +bool is_in_queue(unsigned int channel, struct di_buf_s *di_buf, + int queue_idx); +struct di_buf_s *get_di_buf_head(unsigned int channel, + int queue_idx); + +void queue_init2(unsigned int channel); + +/*new buf:*/ +bool pw_queue_in(unsigned int ch, enum QUE_TYPE qtype, + unsigned int buf_index); +bool pw_queue_out(unsigned int ch, enum QUE_TYPE qtype, + unsigned int *buf_index); +bool pw_queue_empty(unsigned int ch, enum QUE_TYPE qtype); + +/******************************************/ +/*new api*/ +/******************************************/ +union uDI_QBUF_INDEX { + unsigned int d32; + struct { + unsigned int index:8, /*low*/ + type:8, + reserved0:16; + } b; +}; + +void di_que_init(unsigned int ch); +bool di_que_alloc(unsigned int ch); +void di_que_release(unsigned int ch); + +int di_que_is_empty(unsigned int ch, enum QUE_TYPE qtype); +bool di_que_out(unsigned int ch, enum QUE_TYPE qtype, + struct di_buf_s *di_buf); + +struct di_buf_s *di_que_out_to_di_buf(unsigned int ch, + enum QUE_TYPE qtype); +bool di_que_in(unsigned int ch, enum QUE_TYPE qtype, + struct di_buf_s *di_buf); +bool di_que_is_in_que(unsigned int ch, enum QUE_TYPE qtype, + struct di_buf_s *di_buf); +struct di_buf_s *di_que_peek(unsigned int ch, enum QUE_TYPE qtype); +bool di_que_type_2_new(unsigned int q_type, enum QUE_TYPE *nqtype); +int di_que_list_count(unsigned int ch, enum QUE_TYPE qtype); +bool di_que_list(unsigned int ch, enum QUE_TYPE qtype, + unsigned int *outbuf, unsigned int *rsize); + +struct di_buf_s *pw_qindex_2_buf(unsigned int ch, unsigned int qindex); + +void queue_out_dbg(unsigned int channel, struct di_buf_s *di_buf); +#endif /*__DI_QUE_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_reg_tab.c b/drivers/amlogic/media/di_multi/di_reg_tab.c new file mode 100644 index 0000000..750f106 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_reg_tab.c @@ -0,0 +1,249 @@ +/* + * drivers/amlogic/media/di_multi/di_reg_tab.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 "deinterlace.h" +#include "di_data_l.h" +#include "register.h" + +static const struct reg_t rtab_contr[] = { + /*--------------------------*/ + {VD1_AFBCD0_MISC_CTRL, 20, 2, 0, "VD1_AFBCD0_MISC_CTRL", + "vd1_go_field_sel", + "0: gofile;1: post;2: pre"}, + {VD1_AFBCD0_MISC_CTRL, 9, 1, 0, "", + "afbc0_mux_vpp_mad", + "afbc0 to 0:vpp; 1:di"}, + {VD1_AFBCD0_MISC_CTRL, 8, 1, 0, "", + "di_mif0_en", + ":mif to 0-vpp;1-di"}, + /*--------------------------*/ + {DI_POST_CTRL, 12, 1, 0, "DI_POST_CTRL", + "di_post_viu_link", + ""}, + {DI_POST_CTRL, 8, 1, 0, "", + "di_vpp_out_en", + ""}, + /*--------------------------*/ + {VIU_MISC_CTRL0, 20, 1, 0, "VIU_MISC_CTRL0", + "?", + "?"}, + {VIU_MISC_CTRL0, 18, 1, 0, "", + "Vdin0_wr_out_ctrl", + "0: nr_inp to vdin; 1: vdin wr dout"}, + {VIU_MISC_CTRL0, 17, 1, 0, "", + "Afbc_inp_sel", + "0: mif to INP; 1: afbc to INP"}, + {VIU_MISC_CTRL0, 16, 1, 0, "", + "di_mif0_en", + " vd1(afbc) to di post(if0) enable"}, + /*--------------------------*/ + {DI_IF1_GEN_REG, 0, 1, 0, "DI_IF1_GEN_REG", + "enable", + ""}, + + /*--------------------------*/ + {DI_IF1_GEN_REG3, 8, 2, 0, "DI_IF1_GEN_REG3", + "cntl_bits_mode", + "0:8bit;1:10bit 422;2:10bit 444"}, + + /*--------------------------*/ + {DI_IF2_GEN_REG3, 8, 2, 0, "DI_IF2_GEN_REG3", + "cntl_bits_mode", + "0:8bit;1:10bit 422;2:10bit 444"}, + + /*--------------------------*/ + {DI_IF0_GEN_REG3, 8, 2, 0, "DI_IF0_GEN_REG3", + "cntl_bits_mode", + "0:8bit;1:10bit 422;2:10bit 444"}, + + /*--------------------------*/ + {DI_POST_GL_CTRL, 31, 1, 0, "DI_POST_GL_CTRL", + "post count enable", + ""}, + {DI_POST_GL_CTRL, 30, 1, 0, "", + "post count reset", + ""}, + {DI_POST_GL_CTRL, 16, 14, 0, "", + "total line number for post count", + ""}, + {DI_POST_GL_CTRL, 0, 14, 0, "", + "the line number of post frame reset", + ""}, + + {TABLE_FLG_END, 0, 0, 0, "end", "end", ""}, + +}; + +/**********************/ +/* debug register */ +/**********************/ +static unsigned int get_reg_bits(unsigned int val, unsigned int bstart, + unsigned int bw) +{ + return((val & + (((1L << bw) - 1) << bstart)) >> (bstart)); +} + +static void dbg_reg_tab(struct seq_file *s, const struct reg_t *pRegTab) +{ + struct reg_t creg; + int i; + unsigned int l_add; + unsigned int val32 = 1, val; + char *bname; + char *info; + + i = 0; + l_add = 0; + creg = pRegTab[i]; + + do { + if (creg.add != l_add) { + val32 = Rd(creg.add); /*RD*/ + seq_printf(s, "add:0x%x = 0x%08x, %s\n", + creg.add, val32, creg.name); + l_add = creg.add; + } + val = get_reg_bits(val32, creg.bit, creg.wid); /*RD_B*/ + + if (creg.bname) + bname = creg.bname; + else + bname = ""; + if (creg.info) + info = creg.info; + else + info = ""; + + seq_printf(s, "\tbit[%d,%d]:\t0x%x[%d]:\t%s:\t%s\n", + creg.bit, creg.wid, val, val, bname, info); + + i++; + creg = pRegTab[i]; + if (i > TABLE_LEN_MAX) { + pr_info("warn: too long, stop\n"); + break; + } + } while (creg.add != TABLE_FLG_END); +} + +int reg_con_show(struct seq_file *seq, void *v) +{ + dbg_reg_tab(seq, &rtab_contr[0]); + return 0; +} + +static const struct reg_t rtab_cue_int[] = { + /*--------------------------*/ + {NR2_CUE_CON_DIF0, 0, 32, 0x1400, "NR2_CUE_CON_DIF0", + NULL, + NULL}, + {NR2_CUE_CON_DIF1, 0, 32, 0x80064, "NR2_CUE_CON_DIF1", + NULL, + NULL}, + {NR2_CUE_CON_DIF2, 0, 32, 0x80064, "NR2_CUE_CON_DIF2", + NULL, + NULL}, + {NR2_CUE_CON_DIF3, 0, 32, 0x80a0a, "NR2_CUE_CON_DIF3", + NULL, + NULL}, + {NR2_CUE_PRG_DIF, 0, 32, 0x80a0a, "NR2_CUE_PRG_DIF", + NULL, + NULL}, + {TABLE_FLG_END, 0, 0, 0, "end", "end", ""}, + /*--------------------------*/ +}; + +/************************************************ + * register table + ************************************************/ +static bool di_g_rtab_cue(const struct reg_t **tab, unsigned int *tabsize) +{ + *tab = &rtab_cue_int[0]; + *tabsize = ARRAY_SIZE(rtab_cue_int); + + return true; +} + +static unsigned int dim_reg_read(unsigned int addr) +{ + return aml_read_vcbus(addr); +} + +static const struct reg_acc di_pre_regset = { + .wr = dim_DI_Wr, + .rd = dim_reg_read, + .bwr = dim_RDMA_WR_BITS, + .brd = dim_RDMA_RD_BITS, +}; + +static bool di_wr_tab(const struct reg_acc *ops, + const struct reg_t *ptab, unsigned int tabsize) +{ + int i; + const struct reg_t *pl; + + pl = ptab; + + if (!ops || + !tabsize || + !ptab) + return false; + + for (i = 0; i < tabsize; i++) { + if (pl->add == TABLE_FLG_END || + i > TABLE_LEN_MAX) { + break; + } + + if (pl->wid == 32) + ops->wr(pl->add, pl->df_val); + else + ops->bwr(pl->add, pl->df_val, pl->bit, pl->wid); + + pl++; + } + + return true; +} + +bool dim_wr_cue_int(void) +{ + const struct reg_t *ptab; + unsigned int tabsize; + + di_g_rtab_cue(&ptab, &tabsize); + di_wr_tab(&di_pre_regset, + ptab, + tabsize); + PR_INF("%s:finish\n", __func__); + + return true; +} + +int dim_reg_cue_int_show(struct seq_file *seq, void *v) +{ + dbg_reg_tab(seq, &rtab_cue_int[0]); + return 0; +} + diff --git a/drivers/amlogic/media/di_multi/di_reg_tab.h b/drivers/amlogic/media/di_multi/di_reg_tab.h new file mode 100644 index 0000000..215d378 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_reg_tab.h @@ -0,0 +1,26 @@ +/* + * drivers/amlogic/media/di_multi/di_reg_tab.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_REG_TABL_H__ +#define __DI_REG_TABL_H__ + +int reg_con_show(struct seq_file *seq, void *v); + +bool dim_wr_cue_int(void); +int dim_reg_cue_int_show(struct seq_file *seq, void *v); + +#endif /*__DI_REG_TABL_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_sys.c b/drivers/amlogic/media/di_multi/di_sys.c new file mode 100644 index 0000000..64be055 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_sys.c @@ -0,0 +1,754 @@ +/* + * drivers/amlogic/media/di_multi/di_sys.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 + +/*dma_get_cma_size_int_byte*/ +#include + +#include "deinterlace_dbg.h" +#include "deinterlace.h" +#include "di_data_l.h" +#include "di_data.h" +#include "di_dbg.h" +#include "di_vframe.h" +#include "di_task.h" +#include "di_prc.h" +#include "di_sys.h" +#include "di_api.h" + +#include "register.h" +#include "nr_downscale.h" + +static di_dev_t *di_pdev; + +struct di_dev_s *get_dim_de_devp(void) +{ + return di_pdev; +} + +unsigned int di_get_dts_nrds_en(void) +{ + return get_dim_de_devp()->nrds_enable; +} + +/******************************************** + * mem + *******************************************/ + +/********************************************/ +static ssize_t +show_config(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int pos = 0; + + return pos; +} + +static ssize_t show_tvp_region(struct device *dev, + struct device_attribute *attr, char *buff) +{ + ssize_t len = 0; + struct di_dev_s *de_devp = get_dim_de_devp(); + + 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 +ssize_t +show_log(struct device *dev, struct device_attribute *attr, char *buf) +{ + return dim_read_log(buf); +} + +static ssize_t +show_frame_format(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + unsigned int channel = get_current_channel(); /*debug only*/ + struct di_pre_stru_s *ppre = get_pre_stru(channel); + + if (get_init_flag(channel)) + ret += sprintf(buf + ret, "%s\n", + ppre->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 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(provider_vframe_status, 0444, show_vframe_status, NULL); +static DEVICE_ATTR(tvp_region, 0444, show_tvp_region, NULL); + +/********************************************/ +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 */ + file->private_data = NULL; + return 0; +} + +static long di_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + long ret = 0; + + if (_IOC_TYPE(cmd) != _DI_) { + PR_ERR("%s invalid command: %u\n", __func__, cmd); + return -EFAULT; + } + +#if 0 + dbg_reg("no pq\n"); + return 0; +#endif + switch (cmd) { + case AMDI_IOC_SET_PQ_PARM: + ret = dim_pq_load_io(arg); + + break; + default: + break; + } + return ret; +} + +#ifdef CONFIG_COMPAT +static long di_compat_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + unsigned long ret; + + arg = (unsigned long)compat_ptr(arg); + ret = di_ioctl(file, cmd, arg); + return ret; +} +#endif + +static const struct file_operations di_fops = { + .owner = THIS_MODULE, + .open = di_open, + .release = di_release, + .unlocked_ioctl = di_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = di_compat_ioctl, +#endif +}; + +static int dim_rev_mem(struct di_dev_s *di_devp) +{ + unsigned int ch; + unsigned int o_size; + unsigned long rmstart; + unsigned int rmsize; + unsigned int flg_map; + + if (di_devp && !di_devp->flag_cma) { + dil_get_rev_mem(&rmstart, &rmsize); + dil_get_flg(&flg_map); + if (!rmstart) { + PR_ERR("%s:reserved mem start add is 0\n", __func__); + return -1; + } + di_devp->mem_start = rmstart; + di_devp->mem_size = rmsize; + + if (!flg_map) + di_devp->flags |= DI_MAP_FLAG; + + o_size = rmsize / DI_CHANNEL_NUB; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + di_set_mem_info(ch, + di_devp->mem_start + (o_size * ch), + o_size); + PR_INF("rmem:ch[%d]:start:0x%lx, size:%uB\n", + ch, + (di_devp->mem_start + (o_size * ch)), + o_size); + } + PR_INF("rmem:0x%lx, size %uMB.\n", + di_devp->mem_start, (di_devp->mem_size >> 20)); + + di_devp->mem_flg = true; + return 0; + } + PR_INF("%s:no dev or no rev mem\n", __func__); + return -1; +} + +bool dim_rev_mem_check(void)/*tmp*/ +{ + di_dev_t *di_devp = get_dim_de_devp(); + + if (di_devp && !di_devp->flag_cma && di_devp->mem_flg) + return true; + + if (!di_devp) { + PR_ERR("%s:no dev\n", __func__); + return false; + } + PR_INF("%s\n", __func__); + dim_rev_mem(di_devp); + + return true; +} + +#define ARY_MATCH (1) +#ifdef ARY_MATCH + +static const struct di_meson_data data_g12a = { + .name = "dim_g12a", +}; + +static const struct di_meson_data data_sm1 = { + .name = "dim_sm1", +}; + +/* #ifdef CONFIG_USE_OF */ +static const struct of_device_id amlogic_deinterlace_dt_match[] = { + /*{ .compatible = "amlogic, deinterlace", },*/ + { .compatible = "amlogic, dim-g12a", + .data = &data_g12a, + }, { .compatible = "amlogic, dim-g12b", + .data = &data_sm1, + }, { .compatible = "amlogic, dim-sm1", + .data = &data_sm1, + }, {} +}; +#endif +static int dim_probe(struct platform_device *pdev) +{ + int ret = 0; + struct di_dev_s *di_devp = NULL; + int i; +#ifdef ARY_MATCH + const struct of_device_id *match; + struct di_data_l_s *pdata; +#endif + PR_INF("%s:\n", __func__); + +#if 1 /*move from init to here*/ + + di_pdev = kzalloc(sizeof(*di_pdev), GFP_KERNEL); + if (!di_pdev) { + PR_ERR("%s fail to allocate memory.\n", __func__); + goto fail_kmalloc_dev; + } + + /******************/ + ret = alloc_chrdev_region(&di_pdev->devno, 0, DI_COUNT, DEVICE_NAME); + if (ret < 0) { + PR_ERR("%s: failed to allocate major number\n", __func__); + goto fail_alloc_cdev_region; + } + PR_INF("%s: major %d\n", __func__, MAJOR(di_pdev->devno)); + di_pdev->pclss = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(di_pdev->pclss)) { + ret = PTR_ERR(di_pdev->pclss); + PR_ERR("%s: failed to create class\n", __func__); + goto fail_class_create; + } +#endif + + di_devp = di_pdev; + /* *********new********* */ + di_pdev->data_l = NULL; + di_pdev->data_l = kzalloc(sizeof(struct di_data_l_s), GFP_KERNEL); + if (!di_pdev->data_l) { + PR_ERR("%s fail to allocate data l.\n", __func__); + goto fail_kmalloc_datal; + } + /*memset(di_pdev->data_l, 0, sizeof(struct di_data_l_s));*/ + /*pr_info("\tdata size: %ld\n", sizeof(struct di_data_l_s));*/ + /************************/ + if (!dip_prob()) + goto fail_cdev_add; + + di_devp->flags |= DI_SUSPEND_FLAG; + cdev_init(&di_devp->cdev, &di_fops); + di_devp->cdev.owner = THIS_MODULE; + ret = cdev_add(&di_devp->cdev, di_devp->devno, DI_COUNT); + if (ret) + goto fail_cdev_add; + + di_devp->devt = MKDEV(MAJOR(di_devp->devno), 0); + di_devp->dev = device_create(di_devp->pclss, &pdev->dev, + di_devp->devt, di_devp, "di%d", 0); + + if (!di_devp->dev) { + pr_error("device_create create error\n"); + goto fail_cdev_add; + } + dev_set_drvdata(di_devp->dev, di_devp); + platform_set_drvdata(pdev, di_devp); + +#ifdef ARY_MATCH + /************************/ + match = of_match_device(amlogic_deinterlace_dt_match, + &pdev->dev); + if (!match) { + PR_ERR("%s,no matched table\n", __func__); + goto fail_cdev_add; + } + pdata = (struct di_data_l_s *)di_pdev->data_l; + pdata->mdata = match->data; + PR_INF("match name: %s\n", pdata->mdata->name); +#endif + + ret = of_reserved_mem_device_init(&pdev->dev); + if (ret != 0) + PR_INF("no reserved mem.\n"); + + 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_INF("flag_cma=%d\n", di_devp->flag_cma); + + dim_rev_mem(di_devp); + + ret = of_property_read_u32(pdev->dev.of_node, + "nrds-enable", &di_devp->nrds_enable); + ret = of_property_read_u32(pdev->dev.of_node, + "pps-enable", &di_devp->pps_enable); + + /*di pre h scaling down :sm1 tm2*/ + /*pre_hsc_down_en;*/ + di_devp->h_sc_down_en = di_mp_uit_get(eDI_MP_pre_hsc_down_en); + + if (di_devp->flag_cma >= 1) { +#ifdef CONFIG_CMA + di_devp->pdev = pdev; + di_devp->flags |= DI_MAP_FLAG; + #if 0 + di_devp->mem_size = dma_get_cma_size_int_byte(&pdev->dev); + #else + if (di_devp->flag_cma == 1 || + di_devp->flag_cma == 2) { + di_devp->mem_size + = dma_get_cma_size_int_byte(&pdev->dev); + PR_INF("mem size from dts:0x%x\n", di_devp->mem_size); + } + + if (di_devp->mem_size <= 0x800000) {/*need check??*/ + di_devp->mem_size = 0x2800000; + /*(flag_cma ? 3) reserved in*/ + /*codec mm : cma in codec mm*/ + if (di_devp->flag_cma != 3) { + /*no di cma, try use*/ + /*cma from codec mm*/ + di_devp->flag_cma = 4; + } + } + #endif + pr_info("DI: CMA size 0x%x.\n", di_devp->mem_size); + if (di_devp->flag_cma == 2) { + if (dim_cma_alloc_total(di_devp)) + dip_cma_st_set_ready_all(); + } +#endif + } else { + dip_cma_st_set_ready_all(); + } + /* mutex_init(&di_devp->cma_mutex); */ + INIT_LIST_HEAD(&di_devp->pq_table_list); + + atomic_set(&di_devp->pq_flag, 0); + + di_devp->pre_irq = irq_of_parse_and_map(pdev->dev.of_node, 0); + pr_info("pre_irq:%d\n", + di_devp->pre_irq); + di_devp->post_irq = irq_of_parse_and_map(pdev->dev.of_node, 1); + pr_info("post_irq:%d\n", + di_devp->post_irq); + + di_pr_info("%s allocate rdma channel %d.\n", __func__, + di_devp->rdma_handle); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) { + dim_get_vpu_clkb(&pdev->dev, di_devp); + #ifdef CLK_TREE_SUPPORT + clk_prepare_enable(di_devp->vpu_clkb); + pr_info("DI:enable vpu clkb.\n"); + #else + aml_write_hiubus(HHI_VPU_CLKB_CNTL, 0x1000100); + #endif + } + di_devp->flags &= (~DI_SUSPEND_FLAG); + 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__); + + /* set flag to indicate that post_wr is supportted */ + ret = of_property_read_u32(pdev->dev.of_node, + "post-wr-support", + &di_devp->post_wr_support); + if (ret) + dimp_set(eDI_MP_post_wr_support, 0);/*post_wr_support = 0;*/ + else /*post_wr_support = di_devp->post_wr_support;*/ + dimp_set(eDI_MP_post_wr_support, di_devp->post_wr_support); + + ret = of_property_read_u32(pdev->dev.of_node, + "nr10bit-support", + &di_devp->nr10bit_support); + if (ret) + dimp_set(eDI_MP_nr10bit_support, 0);/*nr10bit_support = 0;*/ + else /*nr10bit_support = di_devp->nr10bit_support;*/ + dimp_set(eDI_MP_nr10bit_support, di_devp->nr10bit_support); + +#ifdef DI_USE_FIXED_CANVAS_IDX + if (dim_get_canvas()) { + pr_dbg("DI get canvas error.\n"); + ret = -EEXIST; + return ret; + } +#endif + + 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_provider_vframe_status); + device_create_file(di_devp->dev, &dev_attr_frame_format); + device_create_file(di_devp->dev, &dev_attr_tvp_region); + + /*pd_device_files_add*/ + get_ops_pd()->prob(di_devp->dev); + + get_ops_nr()->nr_drv_init(di_devp->dev); + + for (i = 0; i < DI_CHANNEL_NUB; i++) { + set_init_flag(i, false); + set_reg_flag(i, false); + } + + set_or_act_flag(true); + /*PR_INF("\t 11\n");*/ + ret = devm_request_irq(&pdev->dev, di_devp->pre_irq, &dim_irq, + IRQF_SHARED, + "pre_di", (void *)"pre_di"); + if (di_devp->post_wr_support) { + ret = devm_request_irq(&pdev->dev, di_devp->post_irq, + &dim_post_irq, + IRQF_SHARED, "post_di", + (void *)"post_di"); + } + + di_devp->sema_flg = 1; /*di_sema_init_flag = 1;*/ + dimh_hw_init(dimp_get(eDI_MP_pulldown_enable), + dimp_get(eDI_MP_mcpre_en)); + + dim_set_di_flag(); + + task_start(); + + post_mif_sw(false); + + dim_debugfs_init(); /*2018-07-18 add debugfs*/ + + dimh_patch_post_update_mc_sw(DI_MC_SW_IC, true); + + pr_info("%s:ok\n", __func__); + return ret; + +fail_cdev_add: + pr_info("%s:fail_cdev_add\n", __func__); + kfree(di_devp->data_l); + +fail_kmalloc_datal: + pr_info("%s:fail_kmalloc datal\n", __func__); + +#if 1 /*move from init*/ +/*fail_pdrv_register:*/ + class_destroy(di_pdev->pclss); +fail_class_create: + unregister_chrdev_region(di_pdev->devno, DI_COUNT); +fail_alloc_cdev_region: + kfree(di_pdev); +fail_kmalloc_dev: + + return ret; +#endif + return ret; +} + +static int dim_remove(struct platform_device *pdev) +{ + struct di_dev_s *di_devp = NULL; + + PR_INF("%s:\n", __func__); + di_devp = platform_get_drvdata(pdev); + + dimh_hw_uninit(); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXLX)) + clk_disable_unprepare(di_devp->vpu_clkb); + + di_devp->di_event = 0xff; + + dim_uninit_buf(1, 0);/*channel 0*/ + di_set_flg_hw_int(false); + + task_stop(); + + dim_rdma_exit(); + +/* 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_provider_vframe_status); + device_remove_file(di_devp->dev, &dev_attr_frame_format); + device_remove_file(di_devp->dev, &dev_attr_tvp_region); + /*pd_device_files_del*/ + get_ops_pd()->remove(di_devp->dev); + get_ops_nr()->nr_drv_uninit(di_devp->dev); + cdev_del(&di_devp->cdev); + + if (di_devp->flag_cma == 2) { + if (dma_release_from_contiguous(&pdev->dev, + di_devp->total_pages, + di_devp->mem_size >> PAGE_SHIFT)) { + di_devp->total_pages = NULL; + di_devp->mem_start = 0; + pr_dbg("DI CMA total release ok.\n"); + } else { + pr_dbg("DI CMA total release fail.\n"); + } + if (di_pdev->nrds_enable) { + dim_nr_ds_buf_uninit(di_pdev->flag_cma, + &pdev->dev); + } + } + device_destroy(di_devp->pclss, di_devp->devno); + +/* free drvdata */ + + dev_set_drvdata(&pdev->dev, NULL); + platform_set_drvdata(pdev, NULL); + +#if 1 /*move to remove*/ + class_destroy(di_pdev->pclss); + + dim_debugfs_exit(); + + dip_exit(); + unregister_chrdev_region(di_pdev->devno, DI_COUNT); +#endif + + kfree(di_devp->data_l); + kfree(di_pdev); + + PR_INF("%s:finish\n", __func__); + return 0; +} + +static void dim_shutdown(struct platform_device *pdev) +{ + struct di_dev_s *di_devp = NULL; + int i; + + di_devp = platform_get_drvdata(pdev); + + for (i = 0; i < DI_CHANNEL_NUB; i++) + set_init_flag(i, false); + + if (is_meson_txlx_cpu()) + dim_top_gate_control(true, true); + else + dim_DI_Wr(DI_CLKG_CTRL, 0x2); + + if (!is_meson_txlx_cpu()) + diext_clk_b_sw(false); + + PR_INF("%s.\n", __func__); +} + +#ifdef CONFIG_PM + +static void di_clear_for_suspend(struct di_dev_s *di_devp) +{ + unsigned int channel = get_current_channel(); /*tmp*/ + + pr_info("%s\n", __func__); + + di_vframe_unreg(channel);/*have flag*/ + + if (dip_chst_get(channel) != eDI_TOP_STATE_IDLE) + dim_unreg_process_irq(channel); + + dip_cma_close(); + pr_info("%s end\n", __func__); +} + +/* must called after lcd */ +static int di_suspend(struct device *dev) +{ + struct di_dev_s *di_devp = NULL; + + di_devp = dev_get_drvdata(dev); + di_devp->flags |= DI_SUSPEND_FLAG; + + di_clear_for_suspend(di_devp); + + if (!is_meson_txlx_cpu()) + diext_clk_b_sw(false); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXHD)) + clk_disable_unprepare(di_devp->vpu_clkb); + PR_INF("%s\n", __func__); + return 0; +} + +/* must called before lcd */ +static int di_resume(struct device *dev) +{ + struct di_dev_s *di_devp = NULL; + + PR_INF("%s\n", __func__); + di_devp = dev_get_drvdata(dev); + + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TXL)) + clk_prepare_enable(di_devp->vpu_clkb); + + di_devp->flags &= ~DI_SUSPEND_FLAG; + + /************/ + PR_INF("%s finish\n", __func__); + return 0; +} + +static const struct dev_pm_ops di_pm_ops = { + .suspend_late = di_suspend, + .resume_early = di_resume, +}; +#endif +#ifndef ARY_MATCH +/* #ifdef CONFIG_USE_OF */ +static const struct of_device_id amlogic_deinterlace_dt_match[] = { + /*{ .compatible = "amlogic, deinterlace", },*/ + { .compatible = "amlogic, dim-g12a", }, + {} +}; +#endif +/* #else */ +/* #define amlogic_deinterlace_dt_match NULL */ +/* #endif */ + +static struct platform_driver di_driver = { + .probe = dim_probe, + .remove = dim_remove, + .shutdown = dim_shutdown, + .driver = { + .name = DEVICE_NAME, + .owner = THIS_MODULE, + .of_match_table = amlogic_deinterlace_dt_match, +#ifdef CONFIG_PM + .pm = &di_pm_ops, +#endif + } +}; + +static int __init dim_module_init(void) +{ + int ret = 0; + + PR_INF("%s\n", __func__); + + ret = platform_driver_register(&di_driver); + if (ret != 0) { + PR_ERR("%s: failed to register driver\n", __func__); + /*goto fail_pdrv_register;*/ + return -ENODEV; + } + PR_INF("%s finish\n", __func__); + return 0; +} + +static void __exit dim_module_exit(void) +{ + platform_driver_unregister(&di_driver); + PR_INF("%s: ok.\n", __func__); +} + +module_init(dim_module_init); +module_exit(dim_module_exit); + +MODULE_DESCRIPTION("AMLOGIC MULTI-DI driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION("4.0.0"); + diff --git a/drivers/amlogic/media/di_multi/di_sys.h b/drivers/amlogic/media/di_multi/di_sys.h new file mode 100644 index 0000000..8aec249 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_sys.h @@ -0,0 +1,26 @@ +/* + * drivers/amlogic/media/di_multi/di_sys.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_SYS_H__ +#define __DI_SYS_H__ + +#define DEVICE_NAME "di_multi" +#define CLASS_NAME "deinterlace" + +bool dim_rev_mem_check(void); + +#endif /*__DI_SYS_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_task.c b/drivers/amlogic/media/di_multi/di_task.c new file mode 100644 index 0000000..9912fd4 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_task.c @@ -0,0 +1,315 @@ +/* + * drivers/amlogic/media/di_multi/di_task.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 /*ary add*/ +#include +#include +#include +#include + +#include "deinterlace.h" +#include "di_data_l.h" + +#include "di_prc.h" + +#include "di_task.h" +#include "di_vframe.h" + +static void task_wakeup(struct di_task *tsk); + +unsigned int di_dbg_task_flg; /*debug only*/ + +bool task_send_cmd(unsigned int cmd) +{ + struct di_task *tsk = get_task(); + unsigned int val; + + dbg_reg("%s:cmd[%d]:\n", __func__, cmd); + if (kfifo_is_full(&tsk->fifo_cmd)) { + if (kfifo_out(&tsk->fifo_cmd, &val, sizeof(unsigned int)) + != sizeof(unsigned int)) { + PR_ERR("%s:can't out\n", __func__); + return false; + } + + PR_ERR("%s:lost cmd[%d]\n", __func__, val); + tsk->err_cmd_cnt++; + /*return false;*/ + } + kfifo_in_spinlocked(&tsk->fifo_cmd, &cmd, sizeof(unsigned int), + &tsk->lock_cmd); + + task_wakeup(tsk); + return true; +} + +void task_send_ready(void) +{ + struct di_task *tsk = get_task(); + + task_wakeup(tsk); +} + +#if 0 +bool task_have_vf(unsigned int ch) +{ + struct di_task *tsk = get_task(); + + task_wakeup(tsk); +} +#endif +bool task_get_cmd(unsigned int *cmd) +{ + struct di_task *tsk = get_task(); + unsigned int val; + + if (kfifo_is_empty(&tsk->fifo_cmd)) + return false; + + if (kfifo_out(&tsk->fifo_cmd, &val, sizeof(unsigned int)) + != sizeof(unsigned int)) + return false; + + *cmd = val; + return true; +} + +void task_polling_cmd(void) +{ + int i; + union DI_L_CMD_BITS cmdbyte; + + for (i = 0; i < MAX_KFIFO_L_CMD_NUB; i++) { + if (!task_get_cmd(&cmdbyte.cmd32)) + break; + dip_chst_process_reg(cmdbyte.b.ch); + } +} + +static int task_is_exiting(struct di_task *tsk) +{ + if (tsk->exit) + return 1; + +/* if (afepriv->dvbdev->writers == 1) + * if (time_after_eq(jiffies, fepriv->release_jiffies + + * dvb_shutdown_timeout * HZ)) + * return 1; + */ + return 0; +} + +static int task_should_wakeup(struct di_task *tsk) +{ + if (tsk->wakeup) { + tsk->wakeup = 0; + /*dbg only dbg_tsk("wkg[%d]\n", di_dbg_task_flg);*/ + return 1; + } + return task_is_exiting(tsk); +} + +static void task_wakeup(struct di_task *tsk) +{ + tsk->wakeup = 1; + wake_up_interruptible(&tsk->wait_queue); + /*dbg_tsk("wks[%d]\n", di_dbg_task_flg);*/ +} + +static int di_test_thread(void *data) +{ + struct di_task *tsk = data; + bool semheld = false; + + tsk->delay = HZ; + tsk->status = 0; + tsk->wakeup = 0; + #if 0 + tsk->reinitialise = 0; + tsk->needfinish = 0; + tsk->finishflg = 0; + #endif + set_freezable(); + while (1) { + up(&tsk->sem);/* is locked when we enter the thread... */ +restart: + wait_event_interruptible_timeout(tsk->wait_queue, + task_should_wakeup(tsk) || + kthread_should_stop() || + freezing(current), + tsk->delay); + di_dbg_task_flg = 1; + + if (kthread_should_stop() || task_is_exiting(tsk)) { + /* got signal or quitting */ + if (!down_interruptible(&tsk->sem)) + semheld = true; + tsk->exit = 1; + break; + } + + if (try_to_freeze()) + goto restart; + + if (down_interruptible(&tsk->sem)) + break; +#if 0 + if (tsk->reinitialise) { + /*dvb_frontend_init(fe);*/ + + tsk->reinitialise = 0; + } +#endif + di_dbg_task_flg = 2; + task_polling_cmd(); + di_dbg_task_flg = 3; + dip_chst_process_ch(); + di_dbg_task_flg = 4; + if (get_reg_flag_all()) + dip_hw_process(); + + di_dbg_task_flg = 0; + } + + tsk->thread = NULL; + if (kthread_should_stop()) + tsk->exit = 1; + else + tsk->exit = 0; + /*mb();*/ + + if (semheld) + up(&tsk->sem); + + task_wakeup(tsk);/*?*/ + return 0; +} + +void task_stop(void/*struct di_task *tsk*/) +{ + struct di_task *tsk = get_task(); + +#if 1 /*not use cmd*/ + pr_info("."); + /*--------------------*/ + /*cmd buf*/ + if (tsk->flg_cmd) { + kfifo_free(&tsk->fifo_cmd); + tsk->flg_cmd = 0; + } + /*tsk->lock_cmd = SPIN_LOCK_UNLOCKED;*/ + spin_lock_init(&tsk->lock_cmd); + tsk->err_cmd_cnt = 0; + /*--------------------*/ +#endif + tsk->exit = 1; + /*mb();*/ + + if (!tsk->thread) + return; + + kthread_stop(tsk->thread); + + sema_init(&tsk->sem, 1); + tsk->status = 0; + + /* paranoia check in case a signal arrived */ + if (tsk->thread) + PR_ERR("warning: thread %p won't exit\n", tsk->thread); +} + +int task_start(void) +{ + int ret; + int flg_err; + struct di_task *tsk = get_task(); + + struct task_struct *fe_thread; + struct sched_param param = { .sched_priority = MAX_RT_PRIO - 1 }; + + pr_info("."); + flg_err = 0; +#if 1 /*not use cmd*/ + /*--------------------*/ + /*cmd buf*/ + /*tsk->lock_cmd = SPIN_LOCK_UNLOCKED;*/ + spin_lock_init(&tsk->lock_cmd); + tsk->err_cmd_cnt = 0; + ret = kfifo_alloc(&tsk->fifo_cmd, + sizeof(unsigned int) * MAX_KFIFO_L_CMD_NUB, + GFP_KERNEL); + if (ret < 0) { + tsk->flg_cmd = false; + PR_ERR("%s:can't get kfifo\n", __func__); + return -1; + } + tsk->flg_cmd = true; + +#endif + /*--------------------*/ + sema_init(&tsk->sem, 1); + init_waitqueue_head(&tsk->wait_queue); + + if (tsk->thread) { + if (!tsk->exit) + return 0; + + task_stop(); + } + + if (signal_pending(current)) { + if (tsk->flg_cmd) { + kfifo_free(&tsk->fifo_cmd); + tsk->flg_cmd = 0; + } + return -EINTR; + } + if (down_interruptible(&tsk->sem)) { + if (tsk->flg_cmd) { + kfifo_free(&tsk->fifo_cmd); + tsk->flg_cmd = 0; + } + return -EINTR; + } + + tsk->status = 0; + tsk->exit = 0; + tsk->thread = NULL; + /*mb();*/ + + fe_thread = kthread_run(di_test_thread, tsk, "aml-ditest-0"); + if (IS_ERR(fe_thread)) { + ret = PTR_ERR(fe_thread); + PR_ERR(" failed to start kthread (%d)\n", ret); + up(&tsk->sem); + tsk->flg_init = 0; + return ret; + } + + sched_setscheduler_nocheck(fe_thread, SCHED_FIFO, ¶m); + tsk->flg_init = 1; + tsk->thread = fe_thread; + return 0; +} + +void dbg_task(void) +{ + struct di_task *tsk = get_task(); + + tsk->status = 1; + task_wakeup(tsk); +} diff --git a/drivers/amlogic/media/di_multi/di_task.h b/drivers/amlogic/media/di_multi/di_task.h new file mode 100644 index 0000000..15cbced --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_task.h @@ -0,0 +1,36 @@ +/* + * drivers/amlogic/media/di_multi/di_task.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_TASK_H__ +#define __DI_TASK_H__ + +extern unsigned int di_dbg_task_flg; /*debug only*/ + +enum eTSK_STATE { + eTSK_STATE_IDLE, + eTSK_STATE_WORKING, +}; + +void task_stop(void); +int task_start(void); + +void dbg_task(void); + +bool task_send_cmd(unsigned int cmd); +void task_send_ready(void); + +#endif /*__DI_TASK_H__*/ diff --git a/drivers/amlogic/media/di_multi/di_vframe.c b/drivers/amlogic/media/di_multi/di_vframe.c new file mode 100644 index 0000000..caf2832 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_vframe.c @@ -0,0 +1,556 @@ +/* + * drivers/amlogic/media/di_multi/di_vframe.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 "deinterlace.h" +#include "di_data_l.h" +#include "di_pre.h" +#include "di_prc.h" +#include "di_dbg.h" + +#include "di_vframe.h" + +struct dev_vfram_t *get_dev_vframe(unsigned int ch) +{ + if (ch < DI_CHANNEL_NUB) + return &get_datal()->ch_data[ch].vfm; + + pr_info("err:%s ch overflow %d\n", __func__, ch); + return &get_datal()->ch_data[0].vfm; +} + +const char * const di_rev_name[4] = { + "deinterlace", + "dimulti.1", + "dimulti.2", + "dimulti.3", +}; + +void dev_vframe_reg(struct dev_vfram_t *pvfm) +{ + if (pvfm->reg) { + PR_WARN("duplicate reg\n"); + return; + } + vf_reg_provider(&pvfm->di_vf_prov); + vf_notify_receiver(pvfm->name, VFRAME_EVENT_PROVIDER_START, NULL); + pvfm->reg = 1; +} + +void dev_vframe_unreg(struct dev_vfram_t *pvfm) +{ + if (pvfm->reg) { + vf_unreg_provider(&pvfm->di_vf_prov); + pvfm->reg = 0; + } else { + PR_WARN("duplicate ureg\n"); + } +} + +void di_vframe_reg(unsigned int ch) +{ + struct dev_vfram_t *pvfm; + + pvfm = get_dev_vframe(ch); + + dev_vframe_reg(pvfm); +} + +void di_vframe_unreg(unsigned int ch) +{ + struct dev_vfram_t *pvfm; + + pvfm = get_dev_vframe(ch); + dev_vframe_unreg(pvfm); +} + +/*--------------------------*/ + +const char * const di_receiver_event_cmd[] = { + "", + "_UNREG", + "_LIGHT_UNREG", + "_START", + NULL, /* "_VFRAME_READY", */ + NULL, /* "_QUREY_STATE", */ + "_RESET", + NULL, /* "_FORCE_BLACKOUT", */ + "_REG", + "_LIGHT_UNREG_RETURN_VFRAME", + NULL, /* "_DPBUF_CONFIG", */ + NULL, /* "_QUREY_VDIN2NR", */ + NULL, /* "_SET_3D_VFRAME_INTERLEAVE", */ + NULL, /* "_FR_HINT", */ + NULL, /* "_FR_END_HINT", */ + NULL, /* "_QUREY_DISPLAY_INFO", */ + NULL, /* "_PROPERTY_CHANGED", */ +}; + +#define VFRAME_EVENT_PROVIDER_CMD_MAX 16 + +static int di_receiver_event_fun(int type, void *data, void *arg) +{ + struct dev_vfram_t *pvfm; + unsigned int ch; + int ret = 0; + + ch = *(int *)arg; + + pvfm = get_dev_vframe(ch); + + if (type <= VFRAME_EVENT_PROVIDER_CMD_MAX && + di_receiver_event_cmd[type]) { + dbg_ev("ch[%d]:%s,%d:%s\n", ch, __func__, + type, + di_receiver_event_cmd[type]); + } + + switch (type) { + case VFRAME_EVENT_PROVIDER_UNREG: + ret = di_ori_event_unreg(ch); +/* task_send_cmd(LCMD1(eCMD_UNREG, 0));*/ + break; + case VFRAME_EVENT_PROVIDER_REG: + /*dev_vframe_reg(pvfm);*/ + ret = di_ori_event_reg(data, ch); +/* task_send_cmd(LCMD1(eCMD_REG, 0));*/ + break; + case VFRAME_EVENT_PROVIDER_START: + break; + + case VFRAME_EVENT_PROVIDER_LIGHT_UNREG: + ret = di_ori_event_light_unreg(ch); + break; + case VFRAME_EVENT_PROVIDER_VFRAME_READY: + ret = di_ori_event_ready(ch); + break; + case VFRAME_EVENT_PROVIDER_QUREY_STATE: + ret = di_ori_event_qurey_state(ch); + break; + case VFRAME_EVENT_PROVIDER_RESET: + ret = di_ori_event_reset(ch); + break; + case VFRAME_EVENT_PROVIDER_LIGHT_UNREG_RETURN_VFRAME: + ret = di_ori_event_light_unreg_revframe(ch); + break; + case VFRAME_EVENT_PROVIDER_QUREY_VDIN2NR: + ret = di_ori_event_qurey_vdin2nr(ch); + break; + case VFRAME_EVENT_PROVIDER_SET_3D_VFRAME_INTERLEAVE: + di_ori_event_set_3D(type, data, ch); + break; + case VFRAME_EVENT_PROVIDER_FR_HINT: + case VFRAME_EVENT_PROVIDER_FR_END_HINT: + vf_notify_receiver(pvfm->name, type, data); + break; + + default: + break; + } + + return ret; +} + +static const struct vframe_receiver_op_s di_vf_receiver = { + .event_cb = di_receiver_event_fun +}; + +bool vf_type_is_prog(unsigned int type) +{ + bool ret = (type & VIDTYPE_TYPEMASK) == 0 ? true : false; + + return ret; +} + +bool vf_type_is_interlace(unsigned int type) +{ + bool ret = (type & VIDTYPE_INTERLACE) ? true : false; + + return ret; +} + +bool vf_type_is_top(unsigned int type) +{ + bool ret = ((type & VIDTYPE_TYPEMASK) == VIDTYPE_INTERLACE_TOP) + ? true : false; + return ret; +} + +bool vf_type_is_bottom(unsigned int type) +{ + bool ret = ((type & VIDTYPE_INTERLACE_BOTTOM) + == VIDTYPE_INTERLACE_BOTTOM) + ? true : false; + + return ret; +} + +bool vf_type_is_inter_first(unsigned int type) +{ + bool ret = (type & VIDTYPE_INTERLACE_TOP) ? true : false; + + return ret; +} + +bool vf_type_is_mvc(unsigned int type) +{ + bool ret = (type & VIDTYPE_MVC) ? true : false; + + return ret; +} + +bool vf_type_is_no_video_en(unsigned int type) +{ + bool ret = (type & VIDTYPE_NO_VIDEO_ENABLE) ? true : false; + + return ret; +} + +bool vf_type_is_VIU422(unsigned int type) +{ + bool ret = (type & VIDTYPE_VIU_422) ? true : false; + + return ret; +} + +bool vf_type_is_VIU_FIELD(unsigned int type) +{ + bool ret = (type & VIDTYPE_VIU_FIELD) ? true : false; + + return ret; +} + +bool vf_type_is_VIU_SINGLE(unsigned int type) +{ + bool ret = (type & VIDTYPE_VIU_SINGLE_PLANE) ? true : false; + + return ret; +} + +bool vf_type_is_VIU444(unsigned int type) +{ + bool ret = (type & VIDTYPE_VIU_444) ? true : false; + + return ret; +} + +bool vf_type_is_VIUNV21(unsigned int type) +{ + bool ret = (type & VIDTYPE_VIU_NV21) ? true : false; + + return ret; +} + +bool vf_type_is_vscale_dis(unsigned int type) +{ + bool ret = (type & VIDTYPE_VSCALE_DISABLE) ? true : false; + + return ret; +} + +bool vf_type_is_canvas_toggle(unsigned int type) +{ + bool ret = (type & VIDTYPE_CANVAS_TOGGLE) ? true : false; + + return ret; +} + +bool vf_type_is_pre_interlace(unsigned int type) +{ + bool ret = (type & VIDTYPE_PRE_INTERLACE) ? true : false; + + return ret; +} + +bool vf_type_is_highrun(unsigned int type) +{ + bool ret = (type & VIDTYPE_HIGHRUN) ? true : false; + + return ret; +} + +bool vf_type_is_compress(unsigned int type) +{ + bool ret = (type & VIDTYPE_COMPRESS) ? true : false; + + return ret; +} + +bool vf_type_is_pic(unsigned int type) +{ + bool ret = (type & VIDTYPE_PIC) ? true : false; + + return ret; +} + +bool vf_type_is_scatter(unsigned int type) +{ + bool ret = (type & VIDTYPE_SCATTER) ? true : false; + + return ret; +} + +bool vf_type_is_vd2(unsigned int type) +{ + bool ret = (type & VIDTYPE_VD2) ? true : false; + + return ret; +} + +bool is_bypss_complete(struct dev_vfram_t *pvfm) +{ + return pvfm->bypass_complete; +} + +#if 0 +bool is_reg(unsigned int ch) +{ + struct dev_vfram_t *pvfm; + + pvfm = get_dev_vframe(ch); + + return pvfm->reg; +} +#endif + +void set_bypass_complete(struct dev_vfram_t *pvfm, bool on) +{ + if (on) + pvfm->bypass_complete = true; + else + pvfm->bypass_complete = false; +} + +void set_bypass2_complete(unsigned int ch, bool on) +{ + struct dev_vfram_t *pvfm; + + pvfm = get_dev_vframe(ch); + set_bypass_complete(pvfm, on); +} + +bool is_bypss2_complete(unsigned int ch) +{ + struct dev_vfram_t *pvfm; + + pvfm = get_dev_vframe(ch); + + return is_bypss_complete(pvfm); +} + +#if 0 +static void set_reg(unsigned int ch, int on) +{ + struct dev_vfram_t *pvfm; + + pvfm = get_dev_vframe(ch); + + if (on) + pvfm->reg = true; + else + pvfm->reg = false; +} +#endif +static struct vframe_s *di_vf_peek(void *arg) +{ + unsigned int ch = *(int *)arg; + + /*dim_print("%s:ch[%d]\n",__func__,ch);*/ + if (di_is_pause(ch)) + return NULL; + + if (is_bypss2_complete(ch)) + return pw_vf_peek(ch); + else + return di_vf_l_peek(ch); +} + +static struct vframe_s *di_vf_get(void *arg) +{ + unsigned int ch = *(int *)arg; + /*struct vframe_s *vfm;*/ + + dim_tr_ops.post_get2(5); + if (di_is_pause(ch)) + return NULL; + + di_pause_step_done(ch); + + /*pvfm = get_dev_vframe(ch);*/ + + if (is_bypss2_complete(ch)) + #if 0 + vfm = pw_vf_peek(ch); + if (dim_bypass_detect(ch, vfm)) + return NULL; + + #endif + return pw_vf_get(ch); + + return di_vf_l_get(ch); +} + +static void di_vf_put(struct vframe_s *vf, void *arg) +{ + unsigned int ch = *(int *)arg; + + if (is_bypss2_complete(ch)) { + pw_vf_put(vf, ch); + pw_vf_notify_provider(ch, + VFRAME_EVENT_RECEIVER_PUT, NULL); + return; + } + + di_vf_l_put(vf, ch); +} + +static int di_event_cb(int type, void *data, void *private_data) +{ + if (type == VFRAME_EVENT_RECEIVER_FORCE_UNREG) { + pr_info("%s: RECEIVER_FORCE_UNREG return\n", + __func__); + return 0; + } + return 0; +} + +static int di_vf_states(struct vframe_states *states, void *arg) +{ + unsigned int ch = *(int *)arg; + + if (!states) + return -1; + + dim_print("%s:ch[%d]\n", __func__, ch); + + di_vf_l_states(states, ch); + return 0; +} + +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, +}; + +#if 1 +struct vframe_s *pw_vf_get(unsigned int ch) +{ + sum_g_inc(ch); + return vf_get(di_rev_name[ch]); +} + +struct vframe_s *pw_vf_peek(unsigned int ch) +{ + return vf_peek(di_rev_name[ch]); +} + +void pw_vf_put(struct vframe_s *vf, unsigned int ch) +{ + sum_p_inc(ch); + vf_put(vf, di_rev_name[ch]); +} + +int pw_vf_notify_provider(unsigned int channel, int event_type, void *data) +{ + return vf_notify_provider(di_rev_name[channel], event_type, data); +} + +int pw_vf_notify_receiver(unsigned int channel, int event_type, void *data) +{ + return vf_notify_receiver(di_rev_name[channel], event_type, data); +} + +void pw_vf_light_unreg_provider(unsigned int ch) +{ + struct dev_vfram_t *pvfm; + struct vframe_provider_s *prov; + + pvfm = get_dev_vframe(ch); + + prov = &pvfm->di_vf_prov; + vf_light_unreg_provider(prov); +} + +#else +struct vframe_s *pw_vf_get(unsigned int channel) +{ + return vf_get(VFM_NAME); +} + +struct vframe_s *pw_vf_peek(unsigned int channel) +{ + return vf_peek(VFM_NAME); +} + +void pw_vf_put(struct vframe_s *vf, unsigned int channel) +{ + vf_put(vf, VFM_NAME); +} + +int pw_vf_notify_provider(unsigned int channel, int event_type, void *data) +{ + return vf_notify_provider(VFM_NAME, event_type, data); +} + +int pw_vf_notify_receiver(unsigned int channel, int event_type, void *data) +{ + return vf_notify_receiver(VFM_NAME, event_type, data); +} + +#endif + +void dev_vframe_exit(void) +{ + struct dev_vfram_t *pvfm; + int ch; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + pvfm = get_dev_vframe(ch); + vf_unreg_provider(&pvfm->di_vf_prov); + vf_unreg_receiver(&pvfm->di_vf_recv); + } + pr_info("%s finish\n", __func__); +} + +void dev_vframe_init(void) +{ + struct dev_vfram_t *pvfm; + int ch; + + for (ch = 0; ch < DI_CHANNEL_NUB; ch++) { + pvfm = get_dev_vframe(ch); + pvfm->name = di_rev_name[ch]; + pvfm->indx = ch; + /*set_bypass_complete(pvfm, true);*/ /*test only*/ + + /*receiver:*/ + vf_receiver_init(&pvfm->di_vf_recv, pvfm->name, + &di_vf_receiver, &pvfm->indx); + vf_reg_receiver(&pvfm->di_vf_recv); + + /*provider:*/ + vf_provider_init(&pvfm->di_vf_prov, pvfm->name, + &deinterlace_vf_provider, &pvfm->indx); + } + pr_info("%s finish\n", __func__); +} diff --git a/drivers/amlogic/media/di_multi/di_vframe.h b/drivers/amlogic/media/di_multi/di_vframe.h new file mode 100644 index 0000000..f5eb0d8 --- /dev/null +++ b/drivers/amlogic/media/di_multi/di_vframe.h @@ -0,0 +1,68 @@ +/* + * drivers/amlogic/media/di_multi/di_vframe.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_VFRAME_H__ +#define __DI_VFRAME_H__ + +#include +#include +#include + +void dev_vframe_init(void); +void dev_vframe_exit(void); +void di_vframe_reg(unsigned int ch); +void di_vframe_unreg(unsigned int ch); + +bool vf_type_is_prog(unsigned int type); +bool vf_type_is_interlace(unsigned int type); +bool vf_type_is_top(unsigned int type); +bool vf_type_is_bottom(unsigned int type); +bool vf_type_is_inter_first(unsigned int type); +bool vf_type_is_mvc(unsigned int type); +bool vf_type_is_no_video_en(unsigned int type); +bool vf_type_is_VIU422(unsigned int type); +bool vf_type_is_VIU_FIELD(unsigned int type); +bool vf_type_is_VIU_SINGLE(unsigned int type); +bool vf_type_is_VIU444(unsigned int type); +bool vf_type_is_VIUNV21(unsigned int type); +bool vf_type_is_vscale_dis(unsigned int type); +bool vf_type_is_canvas_toggle(unsigned int type); +bool vf_type_is_pre_interlace(unsigned int type); +bool vf_type_is_highrun(unsigned int type); +bool vf_type_is_compress(unsigned int type); +bool vf_type_is_pic(unsigned int type); +bool vf_type_is_scatter(unsigned int type); +bool vf_type_is_vd2(unsigned int type); + +extern const char * const di_rev_name[4]; + +struct vframe_s *pw_vf_get(unsigned int ch); +struct vframe_s *pw_vf_peek(unsigned int ch); +void pw_vf_put(struct vframe_s *vf, unsigned int ch); +int pw_vf_notify_provider(unsigned int channel, + int event_type, + void *data); +int pw_vf_notify_receiver(unsigned int channel, + int event_type, + void *data); +void pw_vf_light_unreg_provider(unsigned int ch); + +void set_bypass2_complete(unsigned int ch, bool on); +bool is_bypss_complete(struct dev_vfram_t *pvfm); +bool is_bypss2_complete(unsigned int ch); + +#endif /*__DI_VFRAME_H__*/ diff --git a/drivers/amlogic/media/di_multi/dim_trace.h b/drivers/amlogic/media/di_multi/dim_trace.h new file mode 100644 index 0000000..59a5c00 --- /dev/null +++ b/drivers/amlogic/media/di_multi/dim_trace.h @@ -0,0 +1,71 @@ +/* + * drivers/amlogic/media/di_multi/dim_trace.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. + * + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM dim + +#if !defined(_DIM_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _DIM_TRACE_H + +#include + +/* single lifecycle events */ +DECLARE_EVENT_CLASS(di_event_class, + TP_PROTO(const char *name, int field_cnt, unsigned long time), + TP_ARGS(name, field_cnt, time), + TP_STRUCT__entry( + __string(name, name) + __field(int, field_cnt) + __field(unsigned long, time) + ), + TP_fast_assign( + __assign_str(name, name); + __entry->field_cnt = field_cnt; + __entry->time = time; + ), + TP_printk("[%s-%-4dth-%lums]", __get_str(name), + __entry->field_cnt, __entry->time) +); + +#define DEFINE_DI_EVENT(name) \ +DEFINE_EVENT(di_event_class, name, \ + TP_PROTO(const char *name, int field_cnt, unsigned long time), \ + TP_ARGS(name, field_cnt, time)) + +DEFINE_DI_EVENT(dim_pre); +DEFINE_DI_EVENT(dim_post); +/*2019-06-18*/ +DEFINE_DI_EVENT(dim_pre_getxx); +DEFINE_DI_EVENT(dim_pre_setxx); +DEFINE_DI_EVENT(dim_pre_ready); +DEFINE_DI_EVENT(dim_pst_ready); +DEFINE_DI_EVENT(dim_pst_getxx); +DEFINE_DI_EVENT(dim_pst_setxx); +DEFINE_DI_EVENT(dim_pst_irxxx); +DEFINE_DI_EVENT(dim_pst_doing); +DEFINE_DI_EVENT(dim_pst_peekx); +DEFINE_DI_EVENT(dim_pst_get2x); + +#endif /* _DIM_TRACE_H */ + +#if 0 +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE deinterlace_trace +#include +#endif diff --git a/drivers/amlogic/media/di_multi/nr_downscale.c b/drivers/amlogic/media/di_multi/nr_downscale.c new file mode 100644 index 0000000..fc5e561 --- /dev/null +++ b/drivers/amlogic/media/di_multi/nr_downscale.c @@ -0,0 +1,218 @@ +/* + * drivers/amlogic/media/di_multi/nr_downscale.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 "register.h" +#include "nr_downscale.h" +#include "deinterlace.h" + +#include "di_data_l.h" +#include "di_api.h" + +static struct nr_ds_s nrds_dev; + +static void nr_ds_hw_init(unsigned int width, unsigned int height) +{ + unsigned char h_step = 0, v_step = 0; + unsigned int width_out, height_out; + + width_out = NR_DS_WIDTH; + height_out = NR_DS_HEIGHT; + + h_step = width / width_out; + v_step = height / height_out; + + /*Switch MIF to NR_DS*/ + dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, 3, 5, 2); + /* config dsbuf_ocol*/ + dim_RDMA_WR_BITS(NR_DS_BUF_SIZE_REG, width_out, 0, 8); + /* config dsbuf_orow*/ + dim_RDMA_WR_BITS(NR_DS_BUF_SIZE_REG, height_out, 8, 8); + + dim_RDMA_WR_BITS(NRDSWR_X, (width_out - 1), 0, 13); + dim_RDMA_WR_BITS(NRDSWR_Y, (height_out - 1), 0, 13); + + dim_RDMA_WR_BITS(NRDSWR_CAN_SIZE, (height_out - 1), 0, 13); + dim_RDMA_WR_BITS(NRDSWR_CAN_SIZE, (width_out - 1), 16, 13); + /* little endian */ + dim_RDMA_WR_BITS(NRDSWR_CAN_SIZE, 1, 13, 1); + + dim_RDMA_WR_BITS(NR_DS_CTRL, v_step, 16, 6); + dim_RDMA_WR_BITS(NR_DS_CTRL, h_step, 24, 6); +} + +/* + * init nr ds buffer + */ +void dim_nr_ds_buf_init(unsigned int cma_flag, unsigned long mem_start, + struct device *dev) +{ + unsigned int i = 0; + bool ret; + struct dim_mm_s omm; + + if (cma_flag == 0) { + nrds_dev.nrds_addr = mem_start; + } else { + #if 0 + nrds_dev.nrds_pages = dma_alloc_from_contiguous(dev, + NR_DS_PAGE_NUM, 0); + if (nrds_dev.nrds_pages) + nrds_dev.nrds_addr = page_to_phys(nrds_dev.nrds_pages); + else + PR_ERR("DI: alloc nr ds mem error.\n"); + #else + ret = dim_mm_alloc(cma_flag, NR_DS_PAGE_NUM, &omm); + if (ret) { + nrds_dev.nrds_pages = omm.ppage; + nrds_dev.nrds_addr = omm.addr; + } else { + PR_ERR("alloc nr ds mem error.\n"); + } + + #endif + } + for (i = 0; i < NR_DS_BUF_NUM; i++) + nrds_dev.buf[i] = nrds_dev.nrds_addr + (NR_DS_BUF_SIZE * i); + nrds_dev.cur_buf_idx = 0; +} + +void dim_nr_ds_buf_uninit(unsigned int cma_flag, struct device *dev) +{ + unsigned int i = 0; + + if (cma_flag == 0) { + nrds_dev.nrds_addr = 0; + } else { + if (nrds_dev.nrds_pages) { + #if 0 + dma_release_from_contiguous(dev, + nrds_dev.nrds_pages, + NR_DS_PAGE_NUM); + #else + dim_mm_release(cma_flag, + nrds_dev.nrds_pages, + NR_DS_PAGE_NUM, + nrds_dev.nrds_addr); + #endif + nrds_dev.nrds_addr = 0; + nrds_dev.nrds_pages = NULL; + } else + pr_info("DI: no release nr ds mem.\n"); + } + for (i = 0; i < NR_DS_BUF_NUM; i++) + nrds_dev.buf[i] = 0; + nrds_dev.cur_buf_idx = 0; +} + +/* + * hw config, alloc canvas + */ +void dim_nr_ds_init(unsigned int width, unsigned int height) +{ + nr_ds_hw_init(width, height); + nrds_dev.field_num = 0; + + if (nrds_dev.canvas_idx != 0) + return; + + if (ext_ops.canvas_pool_alloc_canvas_table("nr_ds", + &nrds_dev.canvas_idx, 1, CANVAS_MAP_TYPE_1)) { + PR_ERR("%s alloc nrds canvas error.\n", __func__); + return; + } + pr_info("%s alloc nrds canvas %u.\n", + __func__, nrds_dev.canvas_idx); +} + +/* + * config nr ds mif, switch buffer + */ +void dim_nr_ds_mif_config(void) +{ + unsigned long mem_addr = 0; + + mem_addr = nrds_dev.buf[nrds_dev.cur_buf_idx]; + canvas_config(nrds_dev.canvas_idx, mem_addr, + NR_DS_WIDTH, NR_DS_HEIGHT, 0, 0); + dim_RDMA_WR_BITS(NRDSWR_CTRL, + nrds_dev.canvas_idx, 0, 8); + dim_nr_ds_hw_ctrl(true); +} + +/* + * enable/disable nr ds mif&hw + */ +void dim_nr_ds_hw_ctrl(bool enable) +{ + /*Switch MIF to NR_DS*/ + dim_RDMA_WR_BITS(VIUB_MISC_CTRL0, enable ? 3 : 2, 5, 2); + dim_RDMA_WR_BITS(NRDSWR_CTRL, enable ? 1 : 0, 12, 1); + dim_RDMA_WR_BITS(NR_DS_CTRL, enable ? 1 : 0, 30, 1); +} + +/* + * process in irq + */ +void dim_nr_ds_irq(void) +{ + dim_nr_ds_hw_ctrl(false); + nrds_dev.field_num++; + nrds_dev.cur_buf_idx++; + if (nrds_dev.cur_buf_idx >= NR_DS_BUF_NUM) + nrds_dev.cur_buf_idx = 0; +} + +/* + * get buf addr&size for dump + */ +void dim_get_nr_ds_buf(unsigned long *addr, unsigned long *size) +{ + *addr = nrds_dev.nrds_addr; + *size = NR_DS_BUF_SIZE; + pr_info("%s addr 0x%lx, size 0x%lx.\n", + __func__, *addr, *size); +} + +/* + * 0x37f9 ~ 0x37fc 0x3740 ~ 0x3743 8 regs + */ +void dim_dump_nrds_reg(unsigned int base_addr) +{ + unsigned int i = 0x37f9; + + pr_info("-----nrds reg start-----\n"); + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (0x2006 << 2), i, dim_RDMA_RD(0x2006)); + for (i = 0x37f9; i < 0x37fd; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), i, dim_RDMA_RD(i)); + for (i = 0x3740; i < 0x3744; i++) + pr_info("[0x%x][0x%x]=0x%x\n", + base_addr + (i << 2), i, dim_RDMA_RD(i)); + pr_info("-----nrds reg end-----\n"); +} diff --git a/drivers/amlogic/media/di_multi/nr_downscale.h b/drivers/amlogic/media/di_multi/nr_downscale.h new file mode 100644 index 0000000..873ce70 --- /dev/null +++ b/drivers/amlogic/media/di_multi/nr_downscale.h @@ -0,0 +1,46 @@ +/* + * drivers/amlogic/media/di_multi/nr_downscale.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 _NR_DS_H +#define _NR_DS_H + +#define NR_DS_WIDTH 128 +#define NR_DS_HEIGHT 96 +#define NR_DS_BUF_SIZE (96 << 7) +#define NR_DS_BUF_NUM 6 +#define NR_DS_MEM_SIZE (NR_DS_BUF_SIZE * NR_DS_BUF_NUM) +#define NR_DS_PAGE_NUM (NR_DS_MEM_SIZE >> PAGE_SHIFT) + +struct nr_ds_s { + unsigned int field_num; + unsigned long nrds_addr; + struct page *nrds_pages; + unsigned int canvas_idx; + unsigned char cur_buf_idx; + unsigned long buf[NR_DS_BUF_NUM]; +}; + +void dim_nr_ds_buf_init(unsigned int cma_flag, unsigned long mem_start, + struct device *dev); +void dim_nr_ds_buf_uninit(unsigned int cma_flag, struct device *dev); +void dim_nr_ds_init(unsigned int width, unsigned int height); +void dim_nr_ds_mif_config(void); +void dim_nr_ds_hw_ctrl(bool enable); +void dim_nr_ds_irq(void); +void dim_get_nr_ds_buf(unsigned long *addr, unsigned long *size); +void dim_dump_nrds_reg(unsigned int base_addr); +#endif diff --git a/drivers/amlogic/media/di_multi/register.h b/drivers/amlogic/media/di_multi/register.h new file mode 100644 index 0000000..b05814d --- /dev/null +++ b/drivers/amlogic/media/di_multi/register.h @@ -0,0 +1,4416 @@ +/* + * drivers/amlogic/media/di_multi/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_ +#include +#include +#include +#include + +#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 << (len)) - 1) << (start), (val) << (start)) + +#define Rd_reg_bits(adr, start, len) \ + ((aml_read_vcbus(adr) & \ + (((1UL << (len)) - 1UL) << (start))) >> (start)) + +unsigned int dim_RDMA_WR(unsigned int adr, unsigned int val); +unsigned int dim_RDMA_RD(unsigned int adr); +unsigned int dim_RDMA_WR_BITS(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len); +unsigned int dim_RDMA_RD_BITS(unsigned int adr, unsigned int start, + unsigned int len); +void dim_DI_Wr(unsigned int addr, unsigned int val); +void dim_DI_Wr_reg_bits(unsigned int adr, unsigned int val, + unsigned int start, unsigned int len); +void dim_VSYNC_WR_MPEG_REG(unsigned int addr, unsigned int val); +void dim_VSYNC_WR_MPEG_REG_BITS(unsigned int addr, + unsigned int val, + unsigned int start, + unsigned int len); + +#define HHI_VPU_CLKB_CNTL 0x83 + +#define DI_WRARB_REQEN_SLV_L1C1_OLD 0x2795 +#define DI_RDARB_REQEN_SLV_L1C1_OLD 0x2791 +#define DI_ARB_DBG_STAT_L1C1_OLD 0x27b4 + +#define VIUB_SW_RESET 0x2001 +#define VIUB_SW_RESET0 0x2002 +#define VIUB_MISC_CTRL0 0x2006 + /* 0xd0108018 */ +#define VIUB_GCLK_CTRL0 0x2007 +#define VIUB_GCLK_CTRL1 0x2008 +#define VIUB_GCLK_CTRL2 0x2009 +#define VIUB_GCLK_CTRL3 0x200a +/* g12a add debug reg */ +#define DI_DBG_CTRL 0x200b +#define DI_DBG_CTRL1 0x200c +#define DI_DBG_SRDY_INF 0x200d +#define DI_DBG_RRDY_INF 0x200e +/* txl add if2 */ +#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*/ + +/* g12 new added */ +/* IF0 MIF */ +#define DI_IF0_GEN_REG 0x2030 +#define DI_IF0_CANVAS0 0x2031 +#define DI_IF0_LUMA_X0 0x2032 +#define DI_IF0_LUMA_Y0 0x2033 +#define DI_IF0_CHROMA_X0 0x2034 +#define DI_IF0_CHROMA_Y0 0x2035 +#define DI_IF0_REPEAT_LOOP 0x2036 +#define DI_IF0_LUMA0_RPT_PAT 0x2037 +#define DI_IF0_CHROMA0_RPT_PAT 0x2038 +#define DI_IF0_DUMMY_PIXEL 0x2039 +#define DI_IF0_LUMA_FIFO_SIZE 0x203A +#define DI_IF0_RANGE_MAP_Y 0x203B +#define DI_IF0_RANGE_MAP_CB 0x203C +#define DI_IF0_RANGE_MAP_CR 0x203D +#define DI_IF0_GEN_REG2 0x203E +#define DI_IF0_FMT_CTRL 0x203F +#define DI_IF0_FMT_W 0x2040 +#define DI_IF0_FMT_W 0x2040 +#define DI_IF0_URGENT_CTRL 0x2041 +#define DI_IF0_GEN_REG3 0x2042 +/* AXI ARB */ +#define DI_RDARB_MODE_L1C1 0x2050 +#define DI_RDARB_REQEN_SLV_L1C1 0x2051 +#define DI_RDARB_WEIGH0_SLV_L1C1 0x2052 +#define DI_RDARB_WEIGH1_SLV_L1C1 0x2053 +#define DI_WRARB_MODE_L1C1 0x2054 +#define DI_WRARB_REQEN_SLV_L1C1 0x2055 +#define DI_WRARB_WEIGH0_SLV_L1C1 0x2056 +#define DI_WRARB_WEIGH1_SLV_L1C1 0x2057 +#define DI_RDWR_ARB_STATUS_L1C1 0x2058 +#define DI_ARB_DBG_CTRL_L1C1 0x2059 +#define DI_ARB_DBG_STAT_L1C1 0x205a +#define DI_RDARB_UGT_L1C1 0x205b +#define DI_RDARB_LIMT0_L1C1 0x205c +#define DI_WRARB_UGT_L1C1 0x205d +#define DI_PRE_GL_CTRL 0x20ab +#define DI_PRE_GL_THD 0x20ac +#define DI_POST_GL_CTRL 0x20ad +#define DI_POST_GL_THD 0x20ae + +#define DI_SUB_RDARB_MODE 0x37c0 +#define DI_SUB_RDARB_REQEN_SLV 0x37c1 +#define DI_SUB_RDARB_WEIGH0_SLV 0x37c2 +#define DI_SUB_RDARB_WEIGH1_SLV 0x37c3 +#define DI_SUB_RDARB_UGT 0x37c4 +#define DI_SUB_RDARB_LIMT0 0x37c5 +#define DI_SUB_WRARB_MODE 0x37c6 +#define DI_SUB_WRARB_REQEN_SLV 0x37c7 +#define DI_SUB_WRARB_WEIGH0_SLV 0x37c8 +#define DI_SUB_WRARB_WEIGH1_SLV 0x37c9 +#define DI_SUB_WRARB_UGT 0x37ca +#define DI_SUB_RDWR_ARB_STATUS 0x37cb +#define DI_SUB_ARB_DBG_CTRL 0x37cc +#define DI_SUB_ARB_DBG_STAT 0x37cd +#define CONTRD_CTRL1 0x37d0 +#define CONTRD_CTRL2 0x37d1 +#define CONTRD_SCOPE_X 0x37d2 +#define CONTRD_SCOPE_Y 0x37d3 +#define CONTRD_RO_STAT 0x37d4 +#define CONT2RD_CTRL1 0x37d5 +#define CONT2RD_CTRL2 0x37d6 +#define CONT2RD_SCOPE_X 0x37d7 +#define CONT2RD_SCOPE_Y 0x37d8 +#define CONT2RD_RO_STAT 0x37d9 +#define MTNRD_CTRL1 0x37da +#define MTNRD_CTRL2 0x37db +#define MTNRD_SCOPE_X 0x37dc +#define MTNRD_SCOPE_Y 0x37dd +#define MTNRD_RO_STAT 0x37de +#define MCVECRD_CTRL1 0x37df +#define MCVECRD_CTRL2 0x37e0 +#define MCVECRD_SCOPE_X 0x37e1 +#define MCVECRD_SCOPE_Y 0x37e2 +#define MCVECRD_RO_STAT 0x37e3 +#define MCINFRD_CTRL1 0x37e4 +#define MCINFRD_CTRL2 0x37e5 +#define MCINFRD_SCOPE_X 0x37e6 +#define MCINFRD_SCOPE_Y 0x37e7 +#define MCINFRD_RO_STAT 0x37e8 +#define CONTWR_X 0x37e9 +#define CONTWR_Y 0x37ea +#define CONTWR_CTRL 0x37eb +#define CONTWR_CAN_SIZE 0x37ec +#define MTNWR_X 0x37ed +#define MTNWR_Y 0x37ee +#define MTNWR_CTRL 0x37ef +#define MTNWR_CAN_SIZE 0x37f0 +#define MCVECWR_X 0x37f1 +#define MCVECWR_Y 0x37f2 +#define MCVECWR_CTRL 0x37f3 +#define MCVECWR_CAN_SIZE 0x37f4 +#define MCINFWR_X 0x37f5 +#define MCINFWR_Y 0x37f6 +#define MCINFWR_CTRL 0x37f7 +#define MCINFWR_CAN_SIZE 0x37f8 +/* DI SCALE */ +#define DI_SCO_FIFO_CTRL 0x374e +#define DI_SC_TOP_CTRL 0x374f +#define DI_SC_DUMMY_DATA 0x3750 +#define DI_SC_LINE_IN_LENGTH 0x3751 +#define DI_SC_PIC_IN_HEIGHT 0x3752 +#define DI_SC_COEF_IDX 0x3753 +#define DI_SC_COEF 0x3754 +#define DI_VSC_REGION12_STARTP 0x3755 +#define DI_VSC_REGION34_STARTP 0x3756 +#define DI_VSC_REGION4_ENDP 0x3757 +#define DI_VSC_START_PHASE_STEP 0x3758 +#define DI_VSC_REGION0_PHASE_SLOPE 0x3759 +#define DI_VSC_REGION1_PHASE_SLOPE 0x375a +#define DI_VSC_REGION3_PHASE_SLOPE 0x375b +#define DI_VSC_REGION4_PHASE_SLOPE 0x375c +#define DI_VSC_PHASE_CTRL 0x375d +#define DI_VSC_INI_PHASE 0x375e +#define DI_HSC_REGION12_STARTP 0x3760 +#define DI_HSC_REGION34_STARTP 0x3761 +#define DI_HSC_REGION4_ENDP 0x3762 +#define DI_HSC_START_PHASE_STEP 0x3763 +#define DI_HSC_REGION0_PHASE_SLOPE 0x3764 +#define DI_HSC_REGION1_PHASE_SLOPE 0x3765 +#define DI_HSC_REGION3_PHASE_SLOPE 0x3766 +#define DI_HSC_REGION4_PHASE_SLOPE 0x3767 +#define DI_HSC_PHASE_CTRL 0x3768 +#define DI_SC_MISC 0x3769 +#define DI_HSC_PHASE_CTRL1 0x376a +#define DI_HSC_INI_PAT_CTRL 0x376b +#define DI_SC_GCLK_CTRL 0x376c +#define DI_SC_HOLD_LINE 0x376d + +/* DI H DOWN SCALER which IC? */ +#define DI_VIU_HSC_WIDTHM1 0x37b0 +#define DI_VIU_HSC_PHASE_STEP 0x37b1 +#define DI_VIU_HSC_CTRL 0x37b2 +#define DI_VIU_HSC_PHASE_CTRL 0x37b3 +#define DI_VIU_HSC_COEF 0x37b4 +#define DI_VIU_HSC_COEF_IDX 0x37b5 + +/* NR DOWNSAMPLE */ +#define NRDSWR_X 0x37f9 +#define NRDSWR_Y 0x37fa +#define NRDSWR_CTRL 0x37fb +#define NRDSWR_CAN_SIZE 0x37fc +#define NR_DS_BUF_SIZE_REG 0x3740 +#define NR_DS_CTRL 0x3741 +#define NR_DS_OFFSET 0x3742 +#define NR_DS_BLD_COEF 0x3743 +/* 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 */ /*ary : g12a: di_chan3_enable*/ +/* 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)) */ +/* 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)) */ +/* 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) +#define MCDI_PD_22_CHK_FLG_CNT (0x2f5e) +/* 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_LMVLCKSTEXT_0 ((0x2f69)) +#define MCDI_LMVLCKSTEXT_1 ((0x2f6a)) +#define MCDI_LMVLCKEDEXT_0 ((0x2f6b)) +#define MCDI_LMVLCKEDEXT_1 ((0x2f6c)) +#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 +#define DIPD_COMB_CTRL6 0x2feb +/* 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/di_multi/register_nr4.h b/drivers/amlogic/media/di_multi/register_nr4.h new file mode 100644 index 0000000..71d3ace --- /dev/null +++ b/drivers/amlogic/media/di_multi/register_nr4.h @@ -0,0 +1,149 @@ +/* + * drivers/amlogic/media/di_multi/register_nr4.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. + * + */ + +#define NR4_DRT_CTRL ((0x2da4)) +#define NR4_DRT_YSAD_GAIN ((0x2da5)) +#define NR4_DRT_CSAD_GAIN ((0x2da6)) +#define NR4_DRT_SAD_ALP_CORE ((0x2da7)) +#define NR4_DRT_ALP_MINMAX ((0x2da8)) +#define NR4_SNR_CTRL_REG ((0x2da9)) +#define NR4_SNR_ALPHA0_MAX_MIN ((0x2daa)) +#define NR4_ALP0C_ERR2CURV_LIMIT0 ((0x2dab)) +#define NR4_ALP0C_ERR2CURV_LIMIT1 ((0x2dac)) +#define NR4_ALP0Y_ERR2CURV_LIMIT0 ((0x2dad)) +#define NR4_ALP0Y_ERR2CURV_LIMIT1 ((0x2dae)) +#define NR4_SNR_ALPA1_RATE_AND_OFST ((0x2daf)) +#define NR4_SNR_ALPHA1_MAX_MIN ((0x2db0)) +#define NR4_ALP1C_ERR2CURV_LIMIT0 ((0x2db1)) +#define NR4_ALP1C_ERR2CURV_LIMIT1 ((0x2db2)) +#define NR4_ALP1Y_ERR2CURV_LIMIT0 ((0x2db3)) +#define NR4_ALP1Y_ERR2CURV_LIMIT1 ((0x2db4)) +#define NR4_MTN_CTRL ((0x2db5)) +#define NR4_MTN_REF_PAR0 ((0x2db6)) +#define NR4_MTN_REF_PAR1 ((0x2db7)) +#define NR4_MCNR_LUMA_ENH_CTRL ((0x2db8)) +#define NR4_MCNR_LUMA_STAT_LIMTX ((0x2db9)) +#define NR4_MCNR_LUMA_STAT_LIMTY ((0x2dba)) +#define NR4_MCNR_LUMA_DIF_CALC ((0x2dbb)) +#define NR4_MCNR_LUMAPRE_CAL_PRAM ((0x2dbc)) +#define NR4_MCNR_LUMACUR_CAL_PRAM ((0x2dbd)) +#define NR4_MCNR_MV_CTRL_REG ((0x2dbe)) +#define NR4_MCNR_MV_GAIN0 ((0x2dbf)) +#define NR4_MCNR_LMV_PARM ((0x2dc0)) +#define NR4_MCNR_ALP0_REG (0x2dc1) +#define NR4_MCNR_ALP1_AND_BET0_REG (0x2dc2) +#define NR4_MCNR_BET1_AND_BET2_REG (0x2dc3) +#define NR4_MCNR_AC_DC_CRTL (0x2dc4) +#define NR4_MCNR_CM_CTRL0 (0x2dc5) +#define NR4_MCNR_CM_PRAM (0x2dc6) +#define NR4_MCNR_CM_RSHFT_ALP0 (0x2dc7) +#define NR4_MCNR_BLUE_CENT (0x2dc8) +#define NR4_MCNR_BLUE_GAIN_PAR0 (0x2dc9) +#define NR4_MCNR_BLUE_GAIN_PAR1 (0x2dca) +#define NR4_MCNR_CM_BLUE_CLIP0 (0x2dcb) +#define NR4_MCNR_CM_BLUE_CLIP1 (0x2dcc) +#define NR4_MCNR_GREEN_CENT (0x2dcd) +#define NR4_MCNR_GREEN_GAIN_PAR0 (0x2dce) +#define NR4_MCNR_GREEN_GAIN_PAR1 (0x2dcf) +#define NR4_MCNR_GREEN_CLIP0 (0x2dd0) +#define NR4_MCNR_GREEN_CLIP2 (0x2dd1) +#define NR4_MCNR_SKIN_CENT (0x2dd2) +#define NR4_MCNR_SKIN_GAIN_PAR0 (0x2dd3) +#define NR4_MCNR_SKIN_GAIN_PAR1 (0x2dd4) +#define NR4_MCNR_SKIN_CLIP0 (0x2dd5) +#define NR4_MCNR_SKIN_CLIP1 (0x2dd6) +#define NR4_MCNR_ALP1_GLB_CTRL (0x2dd7) +#define NR4_MCNR_DC2NORM_LUT0 (0x2dd8) +#define NR4_MCNR_DC2NORM_LUT1 (0x2dd9) +#define NR4_MCNR_DC2NORM_LUT2 (0x2dda) +#define NR4_MCNR_AC2NORM_LUT0 (0x2ddb) +#define NR4_MCNR_AC2NORM_LUT1 (0x2ddc) +#define NR4_MCNR_AC2NORM_LUT2 (0x2ddd) +#define NR4_MCNR_SAD2ALP0_LUT0 (0x2dde) +#define NR4_MCNR_SAD2ALP0_LUT1 (0x2ddf) +#define NR4_MCNR_SAD2ALP0_LUT2 (0x2de0) +#define NR4_MCNR_SAD2ALP0_LUT3 (0x2de1) +#define NR4_MCNR_SAD2ALP1_LUT0 (0x2de2) +#define NR4_MCNR_SAD2ALP1_LUT1 (0x2de3) +#define NR4_MCNR_SAD2ALP1_LUT2 (0x2de4) +#define NR4_MCNR_SAD2ALP1_LUT3 (0x2de5) +#define NR4_MCNR_SAD2BET0_LUT0 (0x2de6) +#define NR4_MCNR_SAD2BET0_LUT1 (0x2de7) +#define NR4_MCNR_SAD2BET0_LUT2 (0x2de8) +#define NR4_MCNR_SAD2BET0_LUT3 (0x2de9) +#define NR4_MCNR_SAD2BET1_LUT0 (0x2dea) +#define NR4_MCNR_SAD2BET1_LUT1 (0x2deb) +#define NR4_MCNR_SAD2BET1_LUT2 (0x2dec) +#define NR4_MCNR_SAD2BET1_LUT3 (0x2ded) +#define NR4_MCNR_SAD2BET2_LUT0 (0x2dee) +#define NR4_MCNR_SAD2BET2_LUT1 (0x2def) +#define NR4_MCNR_SAD2BET2_LUT2 (0x2df0) +#define NR4_MCNR_SAD2BET2_LUT3 (0x2df1) +#define NR4_MCNR_RO_U_SUM (0x2df2) +#define NR4_MCNR_RO_V_SUM (0x2df3) +#define NR4_MCNR_RO_GRDU_SUM (0x2df4) +#define NR4_MCNR_RO_GRDV_SUM (0x2df5) +#define NR4_TOP_CTRL (0x2dff) +#define NR4_MCNR_SAD_GAIN (0x3700) +#define NR4_MCNR_LPF_CTRL (0x3701) +#define NR4_MCNR_BLD_VS3LUT0 (0x3702) +#define NR4_MCNR_BLD_VS3LUT1 (0x3703) +#define NR4_MCNR_BLD_VS3LUT2 (0x3704) +#define NR4_MCNR_BLD_VS2LUT0 (0x3705) +#define NR4_MCNR_BLD_VS2LUT1 (0x3706) +#define NR4_COEFBLT_LUT10 (0x3707) +#define NR4_COEFBLT_LUT11 (0x3708) +#define NR4_COEFBLT_LUT12 (0x3709) +#define NR4_COEFBLT_LUT20 (0x370a) +#define NR4_COEFBLT_LUT21 (0x370b) +#define NR4_COEFBLT_LUT22 (0x370c) +#define NR4_COEFBLT_LUT30 (0x370d) +#define NR4_COEFBLT_LUT31 (0x370e) +#define NR4_COEFBLT_LUT32 (0x370f) +#define NR4_COEFBLT_CONV (0x3710) +#define NR4_DBGWIN_YX0 (0x3711) +#define NR4_DBGWIN_YX1 (0x3712) +#define NR4_NM_X_CFG (0x3713) +#define NR4_NM_Y_CFG (0x3714) +#define NR4_NM_SAD_THD (0x3715) +#define NR4_MCNR_BANDSPLIT_PRAM (0x3716) +#define NR4_MCNR_ALP1_SGN_COR (0x3717) +#define NR4_MCNR_ALP1_SGN_PRAM (0x3718) +#define NR4_MCNR_ALP1_MVX_LUT1 (0x3719) +#define NR4_MCNR_ALP1_MVX_LUT2 (0x371a) +#define NR4_MCNR_ALP1_MVX_LUT3 (0x371b) +#define NR4_MCNR_ALP1_LP_PRAM (0x371c) +#define NR4_MCNR_ALP1_SGN_LUT1 (0x371d) +#define NR4_MCNR_ALP1_SGN_LUT2 (0x371e) +#define NR4_RO_NM_SAD_SUM (0x371f) +#define NR4_RO_NM_SAD_CNT (0x3720) +#define NR4_RO_NM_VAR_SUM (0x3721) +#define NR4_RO_NM_VAR_SCNT (0x3722) +#define NR4_RO_NM_VAR_MIN_MAX (0x3723) +#define NR4_RO_NR4_DBGPIX_NUM (0x3724) +#define NR4_RO_NR4_BLDVS2_SUM (0x3725) +#define NR4_BLDVS3_SUM (0x3726) +#define NR4_COEF12_SUM (0x3727) +#define NR4_COEF123_SUM (0x3728) +#define NR_DB_FLT_CTRL (0x3738) +#define NR_DB_FLT_YC_THRD (0x3739) +#define NR_DB_FLT_RANDLUT (0x373a) +#define NR_DB_FLT_PXI_THRD (0x373b) +#define NR_DB_FLT_SEED_Y (0x373c) +#define NR_DB_FLT_SEED_V (0x373e) +#define NR_DB_FLT_SEED3 (0x373f) +#define LBUF_TOP_CTRL (0x2fff) diff --git a/include/linux/amlogic/media/vfm/vframe.h b/include/linux/amlogic/media/vfm/vframe.h index 009d49e..1335fe3 100644 --- a/include/linux/amlogic/media/vfm/vframe.h +++ b/include/linux/amlogic/media/vfm/vframe.h @@ -52,6 +52,8 @@ #define VIDTYPE_PRE_DI_AFBC 0x10000000 #define VIDTYPE_RGB_444 0x20000000 +/* 2019-04-22 Suggestions from brian.zhu*/ +#define VIDTYPE_DI_PW 0x40000000 #define DISP_RATIO_FORCECONFIG 0x80000000 #define DISP_RATIO_FORCE_NORMALWIDE 0x40000000 #define DISP_RATIO_FORCE_FULL_STRETCH 0x20000000