vlock: adjust enc mode
authorwenfeng.guo <wenfeng.guo@amlogic.com>
Wed, 16 May 2018 12:17:01 +0000 (20:17 +0800)
committerWenfeng Guo <wenfeng.guo@amlogic.com>
Tue, 29 May 2018 08:51:58 +0000 (01:51 -0700)
PD#162336: vlock: adjust enc mode

1) separate vlock code from amve.c
2) optimize vlock default setting.
3) adjust enc mode
4) add manual enc soft adjust

Change-Id: Ie180c7fb6d9b1aa1fa016dd39bfa401197a5ac85
Signed-off-by: wenfeng.guo <wenfeng.guo@amlogic.com>
MAINTAINERS
drivers/amlogic/media/enhancement/amvecm/Makefile
drivers/amlogic/media/enhancement/amvecm/amve.c
drivers/amlogic/media/enhancement/amvecm/amve.h
drivers/amlogic/media/enhancement/amvecm/amvecm.c
drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h
drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h
drivers/amlogic/media/enhancement/amvecm/vlock.c [new file with mode: 0644]
drivers/amlogic/media/enhancement/amvecm/vlock.h [new file with mode: 0644]
drivers/amlogic/media/vin/tvin/vdin/vdin_ctl.h
drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c

index 92ed2d4..88582bb 100644 (file)
@@ -14464,3 +14464,9 @@ M: xing wang<xing.wang@amlogic.com>
 F: arch/arm64/boot/dts/amlogic/g12a_*
 F: include/linux/amlogic/media/sound/spdif_info.h
 F: sound/soc/amlogic/auge*
+
+AMLOGIC TVIN vlock
+M:      Wenfeng Guo <wenfeng.guo@amlogic.com>
+F:      drivers/amlogic/media/enhancement/amvecm/vlock.c
+F:      drivers/amlogic/media/enhancement/amvecm/vlock.h
+
index a24b8a3..85d4a90 100644 (file)
@@ -3,5 +3,5 @@
 #
 
 obj-$(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) += am_vecm.o
-am_vecm-objs := amve.o amcm.o amcsc.o amvecm.o keystone_correction.o bitdepth.o set_hdr2_v0.o dnlp_cal.o
+am_vecm-objs := amve.o amcm.o amcsc.o amvecm.o keystone_correction.o bitdepth.o set_hdr2_v0.o dnlp_cal.o vlock.o
 
index d4b9f3c..a8d4507 100644 (file)
@@ -33,7 +33,6 @@
 #include "arch/ve_regs.h"
 #include "amve.h"
 #include "amve_gamma_table.h"
-#include "amvecm_vlock_regmap.h"
 #include <linux/io.h>
 #include "dnlp_cal.h"
 
@@ -91,30 +90,6 @@ struct tcon_rgb_ogo_s video_rgb_ogo = {
 
 #define FLAG_LVDS_FREQ_SW1       (1 <<  6)
 
-
-int amvecm_hiu_reg_read(unsigned int reg, unsigned int *val)
-{
-       *val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2));
-       return 0;
-}
-
-int amvecm_hiu_reg_write(unsigned int reg, unsigned int val)
-{
-       writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2)));
-       return 0;
-}
-static int amvecm_hiu_reg_write_bits(unsigned int reg, unsigned int value,
-               unsigned int start, unsigned int len)
-{
-       unsigned int rd_val;
-
-       amvecm_hiu_reg_read(reg, &rd_val);
-       amvecm_hiu_reg_write(reg, ((rd_val &
-            ~(((1L << (len)) - 1) << (start))) |
-           (((value) & ((1L << (len)) - 1)) << (start))));
-       return 0;
-}
-
 int dnlp_en;/* 0:disabel;1:enable */
 module_param(dnlp_en, int, 0664);
 MODULE_PARM_DESC(dnlp_en, "\n enable or disable dnlp\n");
@@ -142,67 +117,6 @@ int video_rgb_ogo_xvy_mtx_latch;
 
 static unsigned int assist_cnt;/* ASSIST_SPARE8_REG1; */
 
-/* video lock */
-/* 0:enc;1:pll;2:manual pll */
-unsigned int vlock_mode = VLOCK_MODE_MANUAL_PLL;
-unsigned int vlock_en = 1;
-
-/*0:only support 50->50;60->60;24->24;30->30;*/
-/*1:support 24/30/50/60/100/120 mix,such as 50->60;*/
-static unsigned int vlock_adapt;
-static unsigned int vlock_dis_cnt_limit = 2;
-static unsigned int vlock_delta_limit = 2;
-/*vlock_debug:bit0:disable info;bit1:format change info;bit2:force reset*/
-static unsigned int vlock_debug;
-static unsigned int vlock_dynamic_adjust = 1;
-
-static unsigned int vlock_sync_limit_flag;
-static unsigned int vlock_state = VLOCK_STATE_NULL;/*1/2/3:vlock step*/
-static enum vmode_e pre_vmode = VMODE_INIT_NULL;
-static enum vframe_source_type_e pre_source_type =
-               VFRAME_SOURCE_TYPE_OTHERS;
-static enum vframe_source_mode_e pre_source_mode =
-               VFRAME_SOURCE_MODE_OTHERS;
-static unsigned int pre_input_freq;
-static unsigned int pre_output_freq;
-static unsigned int vlock_dis_cnt;
-static char pre_vout_mode[64];
-static bool vlock_vmode_changed;
-static unsigned int pre_hiu_reg_m;
-static unsigned int pre_hiu_reg_frac;
-static unsigned int vlock_dis_cnt_no_vf;
-static unsigned int vlock_dis_cnt_no_vf_limit = 5;
-
-static unsigned int vlock_log_cnt;/*cnt base: vlock_log_s*/
-static unsigned int vlock_log_size = 60;/*size base: vlock_log_s*/
-static unsigned int vlock_log_delta_frac = 100;
-static unsigned int vlock_log_delta_ivcnt = 0xff;
-static unsigned int vlock_log_delta_ovcnt = 0xff;
-static unsigned int vlock_log_delta_vcnt = 0xff;
-static unsigned int vlock_log_last_ivcnt;
-static unsigned int vlock_log_last_ovcnt;
-static unsigned int vlock_log_delta_m;
-static unsigned int vlock_log_delta_en;
-module_param(vlock_log_size, uint, 0664);
-MODULE_PARM_DESC(vlock_log_size, "\n vlock_log_size\n");
-module_param(vlock_log_cnt, uint, 0664);
-MODULE_PARM_DESC(vlock_log_cnt, "\n vlock_log_cnt\n");
-module_param(vlock_log_delta_frac, uint, 0664);
-MODULE_PARM_DESC(vlock_log_delta_frac, "\n vlock_log_delta_frac\n");
-module_param(vlock_log_delta_m, uint, 0664);
-MODULE_PARM_DESC(vlock_log_delta_m, "\n vlock_log_delta_m\n");
-module_param(vlock_log_delta_en, uint, 0664);
-MODULE_PARM_DESC(vlock_log_delta_en, "\n vlock_log_delta_en\n");
-
-module_param(vlock_log_delta_ivcnt, uint, 0664);
-MODULE_PARM_DESC(vlock_log_delta_ivcnt, "\n vlock_log_delta_ivcnt\n");
-
-module_param(vlock_log_delta_ovcnt, uint, 0664);
-MODULE_PARM_DESC(vlock_log_delta_ovcnt, "\n vlock_log_delta_ovcnt\n");
-
-module_param(vlock_log_delta_vcnt, uint, 0664);
-MODULE_PARM_DESC(vlock_log_delta_vcnt, "\n vlock_log_delta_vcnt\n");
-static unsigned int vlock_log_en;
 /* 3d sync parts begin */
 unsigned int sync_3d_h_start;
 unsigned int sync_3d_h_end;
@@ -1070,610 +984,6 @@ void ve_ogo_param_update(void)
        vecm_latch_flag |= FLAG_RGB_OGO;
 }
 
-static unsigned int vlock_check_input_hz(struct vframe_s *vf)
-{
-       unsigned int ret_hz = 0;
-       unsigned int duration = vf->duration;
-
-       if ((vf->source_type != VFRAME_SOURCE_TYPE_CVBS) &&
-               (vf->source_type != VFRAME_SOURCE_TYPE_HDMI))
-               ret_hz = 0;
-       else if (vf->source_type == VFRAME_SOURCE_TYPE_HDMI) {
-               if (duration != 0)
-                       ret_hz = (96000 + duration/2)/duration;
-       } else if (vf->source_type == VFRAME_SOURCE_TYPE_CVBS) {
-               if (vf->source_mode == VFRAME_SOURCE_MODE_NTSC)
-                       ret_hz = 60;
-               else if ((vf->source_mode == VFRAME_SOURCE_MODE_PAL) ||
-                       (vf->source_mode == VFRAME_SOURCE_MODE_SECAM))
-                       ret_hz = 50;
-               else
-                       ret_hz = 0;
-       }
-       return ret_hz;
-}
-
-static unsigned int vlock_check_output_hz(unsigned int sync_duration_num)
-{
-       unsigned int ret_hz = 0;
-
-       switch (sync_duration_num) {
-       case 24:
-               ret_hz = 24;
-               break;
-       case 30:
-               ret_hz = 30;
-               break;
-       case 50:
-               ret_hz = 50;
-               break;
-       case 60:
-               ret_hz = 60;
-               break;
-       case 100:
-               ret_hz = 100;
-               break;
-       case 120:
-               ret_hz = 120;
-               break;
-       default:
-               ret_hz = 0;
-               break;
-       }
-       return ret_hz;
-}
-static void vlock_enable(bool enable)
-{
-       unsigned int tmp_value;
-
-       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
-       if (is_meson_gxtvbb_cpu()) {
-               if (vlock_mode == VLOCK_MODE_MANUAL_PLL) {
-                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 20, 1);
-                       if (is_meson_gxtvbb_cpu() &&
-                               (((tmp_value >> 21) & 0x3) != 2))
-                               amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6,
-                                       2, 21, 2);
-               } else
-                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6,
-                               enable, 20, 1);
-       } else if (is_meson_txl_cpu() || is_meson_txlx_cpu()) {
-               if (vlock_mode == VLOCK_MODE_MANUAL_PLL)
-                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5, 0, 3, 1);
-               else
-                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5,
-                               enable, 3, 1);
-       }
-}
-static void vlock_setting(struct vframe_s *vf,
-               unsigned int input_hz, unsigned int output_hz)
-{
-       unsigned int freq_hz = 0, hiu_reg_value_2_addr = HHI_HDMI_PLL_CNTL2;
-       unsigned int reg_value = 0, hiu_reg_value, hiu_reg_value_2;
-       unsigned int hiu_m_val, hiu_frac_val;
-
-       amvecm_hiu_reg_write(HHI_VID_LOCK_CLK_CNTL, 0x80);
-       if (vlock_mode == VLOCK_MODE_ENC) {
-               am_set_regmap(&vlock_enc_lcd720x480);
-               /* VLOCK_CNTL_EN disable */
-               vlock_enable(0);
-               /* disable to adjust pll */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 29, 1);
-               /* CFG_VID_LOCK_ADJ_EN enable */
-               WRITE_VPP_REG_BITS(ENCL_MAX_LINE_SWITCH_POINT, 1, 13, 1);
-               /* enable to adjust pll */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 30, 1);
-               /*clear accum1 value*/
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
-               /*clear accum0 value*/
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
-       }
-       if ((vlock_mode == VLOCK_MODE_AUTO_PLL) ||
-               (vlock_mode == VLOCK_MODE_MANUAL_PLL)) {
-               /* av pal in,1080p60 hdmi out as default */
-               if ((vlock_debug & 0x1000) == 0)
-                       am_set_regmap(&vlock_pll_in50hz_out60hz);
-               /*set input & output freq*/
-               /*bit0~7:input freq*/
-               /*bit8~15:output freq*/
-               freq_hz = input_hz | (output_hz << 8);
-               WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16);
-               /*Ifrm_cnt_mod:0x3001(bit23~16);*/
-               /*(output_freq/input_freq)*Ifrm_cnt_mod must be integer*/
-               if (vlock_adapt == 0)
-                       WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, 1, 16, 8);
-               else
-                       WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
-                               input_hz, 16, 8);
-               /*set PLL M_INT;PLL M_frac*/
-               /* WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, */
-               /* READ_CBUS_REG_BITS(HHI_HDMI_PLL_CNTL,0,9),12,9); */
-               amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &hiu_reg_value);
-               amvecm_hiu_reg_read(hiu_reg_value_2_addr,
-                       &hiu_reg_value_2);
-               if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) {
-                       hiu_m_val = hiu_reg_value & 0x1FF;
-                       hiu_frac_val = hiu_reg_value_2 & 0x3FF;
-                       if (hiu_reg_value_2 & 0x800) {
-                               hiu_m_val -= 1;
-                               if (hiu_reg_value_2 & 0x400)
-                                       hiu_m_val -= 1;
-                               hiu_frac_val = 0x400 -
-                                       ((~(hiu_frac_val - 1)) & 0x3ff);
-                       } else if (hiu_reg_value_2 & 0x400) {
-                               hiu_m_val += 1;
-                       }
-                       reg_value = (hiu_m_val << 12)
-                               + (hiu_frac_val << 2);
-               }
-               WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, reg_value, 0, 21);
-
-               /* vlock module output goes to which module */
-               switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL, 0, 2)) {
-               case 0:/* ENCL */
-                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 26, 2);
-                       break;
-               case 1:/* ENCI */
-                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 2, 26, 2);
-                       break;
-               case 2: /* ENCP */
-                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 26, 2);
-                       break;
-               default:
-                       break;
-               }
-               /*enable vlock to adj pll*/
-               /* CFG_VID_LOCK_ADJ_EN disable */
-               WRITE_VPP_REG_BITS(ENCL_MAX_LINE_SWITCH_POINT, 0, 13, 1);
-               /* disable to adjust pll */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 30, 1);
-               /* VLOCK_CNTL_EN enable */
-               vlock_enable(1);
-               /* enable to adjust pll */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 29, 1);
-       }
-       if ((vf->source_type == VFRAME_SOURCE_TYPE_TUNER) ||
-               (vf->source_type == VFRAME_SOURCE_TYPE_CVBS))
-               /* Input Vsync source select from tv-decoder */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 2, 16, 3);
-       else if (vf->source_type == VFRAME_SOURCE_TYPE_HDMI)
-               /* Input Vsync source select from hdmi-rx */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 16, 3);
-       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 31, 1);
-}
-void vlock_vmode_check(void)
-{
-       const struct vinfo_s *vinfo;
-       unsigned int tmp_value, hiu_reg_addr;
-       char cur_vout_mode[64];
-
-       if (vlock_en == 0)
-               return;
-
-       if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
-               hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
-       else
-               hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
-
-       vinfo = get_current_vinfo();
-       vlock_vmode_changed = 0;
-       memset(cur_vout_mode, 0, sizeof(cur_vout_mode));
-       strcpy(cur_vout_mode, vinfo->name);
-       if (strcmp(cur_vout_mode, pre_vout_mode) != 0) {
-               amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
-               pre_hiu_reg_frac = tmp_value & 0xfff;
-               amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
-               pre_hiu_reg_m = tmp_value & 0x1ff;
-               if (vlock_debug & 0x10)
-                       pr_info("[%s]:vout mode changed:%s==>%s\n",
-                               __func__, pre_vout_mode, cur_vout_mode);
-               memset(pre_vout_mode, 0, sizeof(pre_vout_mode));
-               strcpy(pre_vout_mode, cur_vout_mode);
-               vlock_vmode_changed = 1;
-       }
-}
-static void vlock_disable_step1(void)
-{
-       unsigned int m_reg_value, tmp_value;
-       unsigned int hiu_reg_addr;
-
-       /* VLOCK_CNTL_EN disable */
-       vlock_enable(0);
-       vlock_vmode_check();
-       if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
-               hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
-       else
-               hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
-
-       amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
-       m_reg_value = tmp_value & 0xfff;
-       if ((m_reg_value != pre_hiu_reg_frac) &&
-               (pre_hiu_reg_m != 0)) {
-               tmp_value = (tmp_value & 0xfffff000) |
-                       (pre_hiu_reg_frac & 0xfff);
-               amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
-       }
-       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
-       m_reg_value = tmp_value & 0x1ff;
-       if ((m_reg_value != pre_hiu_reg_m) &&
-               (pre_hiu_reg_m != 0)) {
-               tmp_value = (tmp_value & 0xfffffe00) |
-                       (pre_hiu_reg_m & 0x1ff);
-               amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
-       }
-       vlock_dis_cnt = vlock_dis_cnt_limit;
-       memset(pre_vout_mode, 0, sizeof(pre_vout_mode));
-       pre_vmode = VMODE_INIT_NULL;
-       pre_source_type = VFRAME_SOURCE_TYPE_OTHERS;
-       pre_source_mode = VFRAME_SOURCE_MODE_OTHERS;
-       pre_input_freq = 0;
-       pre_output_freq = 0;
-       vlock_state = VLOCK_STATE_DISABLE_STEP1_DONE;
-}
-
-static void vlock_disable_step2(void)
-{
-       unsigned int temp_val;
-       /* need delay to disable follow regs(vlsi suggest!!!) */
-       if (vlock_dis_cnt > 0)
-               vlock_dis_cnt--;
-       if (vlock_dis_cnt == 0) {
-               /* disable to adjust pll */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 29, 1);
-               /* CFG_VID_LOCK_ADJ_EN disable */
-               WRITE_VPP_REG_BITS(ENCL_MAX_LINE_SWITCH_POINT,
-                               0, 13, 1);
-               /* disable to adjust pll */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 30, 1);
-               /* disable vid_lock_en */
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 31, 1);
-               vlock_state = VLOCK_STATE_DISABLE_STEP2_DONE;
-               amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val);
-               if (is_meson_gxtvbb_cpu() && (((temp_val >> 21) & 0x3) != 0))
-                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 21, 2);
-       }
-}
-static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo,
-       unsigned int input_hz, unsigned int output_hz)
-{
-       vlock_setting(vf, input_hz, output_hz);
-       if (vlock_debug & 0x10) {
-               pr_info("%s:vmode/source_type/source_mode/input_freq/output_freq:\n",
-                       __func__);
-               pr_info("\t%d/%d/%d/%d/%d=>%d/%d/%d/%d/%d\n",
-                       pre_vmode, pre_source_type, pre_source_mode,
-                       pre_input_freq, pre_output_freq,
-                       vinfo->mode, vf->source_type, vf->source_mode,
-                       input_hz, output_hz);
-       }
-       pre_vmode = vinfo->mode;
-       pre_source_type = vf->source_type;
-       pre_source_mode = vf->source_mode;
-       pre_input_freq = input_hz;
-       pre_output_freq = output_hz;
-       vlock_sync_limit_flag = 0;
-       vlock_vmode_changed = 0;
-       vlock_dis_cnt = 0;
-       vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
-       vlock_log_cnt = 0;
-}
-#define VLOCK_REG_NUM  33
-struct vlock_log_s {
-       unsigned int pll_m;
-       unsigned int pll_frac;
-       unsigned int vlock_regs[VLOCK_REG_NUM];
-};
-struct vlock_log_s *vlock_log;
-
-void vlock_log_start(void)
-{
-       unsigned int size_mem;
-
-       size_mem = vlock_log_size * sizeof(struct vlock_log_s);
-       vlock_log = kzalloc(size_mem, GFP_KERNEL);
-
-       if (vlock_log == NULL) {
-               kfree(vlock_log);
-               return;
-       }
-
-       vlock_log_en = 1;
-       pr_info("%s done\n", __func__);
-}
-void vlock_log_stop(void)
-{
-       if (vlock_log != NULL)
-               kfree(vlock_log);
-       vlock_log_en = 0;
-       pr_info("%s done\n", __func__);
-}
-void vlock_log_print(void)
-{
-       unsigned int i, j;
-
-       for (i = 0; i < vlock_log_size; i++) {
-               pr_info("\n*******[%d]pll_m:0x%x,pll_frac:0x%x*******\n",
-                       i, vlock_log[i].pll_m, vlock_log[i].pll_frac);
-               for (j = 0; j < VLOCK_REG_NUM;) {
-                       if ((j%8 == 0) && ((j + 7) < VLOCK_REG_NUM)) {
-                               pr_info("0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
-                                       vlock_log[i].vlock_regs[j],
-                                       vlock_log[i].vlock_regs[j+1],
-                                       vlock_log[i].vlock_regs[j+2],
-                                       vlock_log[i].vlock_regs[j+3],
-                                       vlock_log[i].vlock_regs[j+4],
-                                       vlock_log[i].vlock_regs[j+5],
-                                       vlock_log[i].vlock_regs[j+6],
-                                       vlock_log[i].vlock_regs[j+7]);
-                               j += 8;
-                       } else {
-                               pr_info("0x%08x\t",
-                                       vlock_log[i].vlock_regs[j]);
-                               j++;
-                       }
-
-               }
-       }
-       pr_info("%s done\n", __func__);
-}
-
-static void vlock_enable_step3(void)
-{
-       unsigned int m_reg_value, tmp_value, abs_val;
-       unsigned int hiu_reg_addr, i;
-
-       if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
-               hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
-       else
-               hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
-
-       /*vs_i*/
-       tmp_value = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
-       abs_val = abs(vlock_log_last_ivcnt - tmp_value);
-       if ((abs_val > vlock_log_delta_ivcnt) &&
-               (vlock_log_delta_en & (1 << 0)))
-               pr_info("%s: abs_ivcnt over 0x%x:0x%x(last:0x%x,cur:0x%x)\n",
-                       __func__, vlock_log_delta_ivcnt,
-                       abs_val, vlock_log_last_ivcnt, tmp_value);
-       vlock_log_last_ivcnt = tmp_value;
-       /*vs_o*/
-       tmp_value = READ_VPP_REG(VPU_VLOCK_RO_VS_O_DIST);
-       abs_val = abs(vlock_log_last_ovcnt - tmp_value);
-       if ((abs_val > vlock_log_delta_ovcnt) &&
-               (vlock_log_delta_en & (1 << 1)))
-               pr_info("%s: abs_ovcnt over 0x%x:0x%x(last:0x%x,cur:0x%x)\n",
-                       __func__, vlock_log_delta_ovcnt,
-                       abs_val, vlock_log_last_ivcnt, tmp_value);
-       vlock_log_last_ovcnt = tmp_value;
-       /*delta_vs*/
-       abs_val = abs(vlock_log_last_ovcnt - vlock_log_last_ivcnt);
-       if ((abs_val > vlock_log_delta_vcnt) && (vlock_log_delta_en & (1 << 2)))
-               pr_info("%s: abs_vcnt over 0x%x:0x%x(ivcnt:0x%x,ovcnt:0x%x)\n",
-                       __func__, vlock_log_delta_vcnt,
-                       abs_val, vlock_log_last_ivcnt, vlock_log_last_ovcnt);
-
-       m_reg_value = READ_VPP_REG(VPU_VLOCK_RO_M_INT_FRAC);
-       if (vlock_log_en && (vlock_log_cnt < vlock_log_size)) {
-               vlock_log[vlock_log_cnt].pll_frac = (m_reg_value & 0xfff) >> 2;
-               vlock_log[vlock_log_cnt].pll_m = (m_reg_value >> 16) & 0x1ff;
-               for (i = 0; i < VLOCK_REG_NUM; i++)
-                       vlock_log[vlock_log_cnt].vlock_regs[i] =
-                               READ_VPP_REG(0x3000 + i);
-               vlock_log_cnt++;
-       }
-       if (m_reg_value == 0) {
-               vlock_state = VLOCK_STATE_ENABLE_FORCE_RESET;
-               if (vlock_debug & 0x100)
-                       pr_info("%s:vlock work abnormal! force reset vlock\n",
-                               __func__);
-               return;
-       }
-       /*vlsi suggest config:don't enable load signal,*/
-       /*on gxtvbb this load signal will effect SSG,*/
-       /*which may result in flashes black*/
-       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
-       if (is_meson_gxtvbb_cpu() && (((tmp_value >> 21) & 0x3) != 2))
-               amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 2, 21, 2);
-       /*frac*/
-       amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
-       abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff));
-       if ((abs_val > vlock_log_delta_frac) &&
-               (vlock_log_delta_en & (1 << 3)))
-               pr_info("vlock frac delta:%d(0x%x,0x%x)\n",
-                       abs_val, ((m_reg_value & 0xfff) >> 2),
-                       (tmp_value & 0xfff));
-       if (abs_val > vlock_delta_limit) {
-               tmp_value = (tmp_value & 0xfffff000) |
-                       ((m_reg_value & 0xfff) >> 2);
-               amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
-       }
-       /*m*/
-       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
-       abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (tmp_value & 0x1ff));
-       if ((abs_val > vlock_log_delta_m) && (vlock_log_delta_en & (1 << 4)))
-               pr_info("vlock m delta:%d(0x%x,0x%x)\n",
-                       abs_val, ((m_reg_value >> 16) & 0x1ff),
-                       (tmp_value & 0x1ff));
-       if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) {
-               tmp_value = (tmp_value & 0xfffffe00) |
-                       ((m_reg_value >> 16) & 0x1ff);
-               amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
-       }
-}
-/* won't change this function internal seqence,*/
-/* if really need change,please be carefull */
-void amve_vlock_process(struct vframe_s *vf)
-{
-       struct vinfo_s *vinfo;
-       unsigned int input_hz, output_hz, input_vs_cnt;
-
-       if (vecm_latch_flag & FLAG_VLOCK_DIS) {
-               vlock_disable_step1();
-               vlock_en = 0;
-               vecm_latch_flag &= ~FLAG_VLOCK_DIS;
-               if (vlock_debug & 0x1)
-                       pr_info("[%s]disable vlock module!!!\n", __func__);
-               return;
-       }
-       vinfo = get_current_vinfo();
-       input_hz = vlock_check_input_hz(vf);
-       output_hz = vlock_check_output_hz(vinfo->sync_duration_num);
-       vlock_dis_cnt_no_vf = 0;
-       if (vecm_latch_flag & FLAG_VLOCK_EN) {
-               vlock_enable_step1(vf, vinfo, input_hz, output_hz);
-               vlock_en = 1;
-               vecm_latch_flag &= ~FLAG_VLOCK_EN;
-       }
-       if (vlock_state == VLOCK_STATE_DISABLE_STEP1_DONE) {
-               vlock_disable_step2();
-               return;
-       }
-       if (vlock_en == 1) {
-               if (((input_hz != output_hz) && (vlock_adapt == 0)) ||
-                       (input_hz == 0) || (output_hz == 0) ||
-                       (((vf->type_original & VIDTYPE_TYPEMASK)
-                               != VIDTYPE_PROGRESSIVE) &&
-                               is_meson_txlx_package_962E())) {
-                       if ((vlock_state != VLOCK_STATE_DISABLE_STEP2_DONE) &&
-                               (vlock_state != VLOCK_STATE_NULL))
-                               vlock_disable_step1();
-                       if (vlock_debug & 0x1)
-                               pr_info("[%s]auto disable vlock module for no support case!!!\n",
-                                       __func__);
-                       return;
-               }
-               vlock_vmode_check();
-               if ((vinfo->mode != pre_vmode) ||
-                       (vf->source_type != pre_source_type) ||
-                       (vf->source_mode != pre_source_mode) ||
-                       (input_hz != pre_input_freq) ||
-                       (output_hz != pre_output_freq) ||
-                       vlock_vmode_changed ||
-                       (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET))
-                       vlock_enable_step1(vf, vinfo, input_hz, output_hz);
-               if ((vlock_sync_limit_flag < 10) &&
-                       (vlock_state >= VLOCK_STATE_ENABLE_STEP1_DONE))
-                       vlock_sync_limit_flag++;
-               if ((vlock_sync_limit_flag == 5) &&
-                       (vlock_state == VLOCK_STATE_ENABLE_STEP1_DONE)) {
-                       /*input_vs_cnt =*/
-                       /*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/
-                       /*      0, 28);*/
-                       input_vs_cnt = XTAL_VLOCK_CLOCK/input_hz;
-                       WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MAX,
-                                       input_vs_cnt*125/100);
-                       WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MIN,
-                                       input_vs_cnt*70/100);
-                       /*cal accum1 value*/
-                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
-                       /*cal accum0 value*/
-                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
-                       vlock_state = VLOCK_STATE_ENABLE_STEP2_DONE;
-               } else if (vlock_dynamic_adjust &&
-                       (vlock_sync_limit_flag > 5) &&
-                       (vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) &&
-                       (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) &&
-                       (vlock_mode == VLOCK_MODE_MANUAL_PLL)) {
-                       vlock_enable_step3();
-               }
-       }
-}
-
-void amve_vlock_resume(void)
-{
-       if ((vlock_en == 0) || (vlock_state ==
-               VLOCK_STATE_DISABLE_STEP2_DONE) ||
-               (vlock_state == VLOCK_STATE_NULL))
-               return;
-       if (vlock_state == VLOCK_STATE_DISABLE_STEP1_DONE) {
-               vlock_disable_step2();
-               return;
-       }
-       vlock_dis_cnt_no_vf++;
-       if ((vlock_state != VLOCK_STATE_DISABLE_STEP2_DONE) &&
-               (vlock_dis_cnt_no_vf > vlock_dis_cnt_no_vf_limit)) {
-               vlock_disable_step1();
-               vlock_dis_cnt_no_vf = 0;
-               if (vlock_debug & 0x1)
-                       pr_info("[%s]auto disable vlock module for no vframe & run disable step1.!!!\n",
-                               __func__);
-       }
-       if (vlock_debug & 0x1)
-               pr_info("[%s]auto disable vlock module for no vframe!!!\n",
-                       __func__);
-       if (vlock_dynamic_adjust &&
-               (vlock_sync_limit_flag > 5) &&
-               (vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) &&
-               (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) &&
-               (vlock_mode == VLOCK_MODE_MANUAL_PLL))
-               vlock_enable_step3();
-}
-
-void vlock_param_set(unsigned int val, enum vlock_param_e sel)
-{
-       switch (sel) {
-       case VLOCK_EN:
-               vlock_en = val;
-               break;
-       case VLOCK_ADAPT:
-               vlock_adapt = val;
-               break;
-       case VLOCK_MODE:
-               vlock_mode = val;
-               break;
-       case VLOCK_DIS_CNT_LIMIT:
-               vlock_dis_cnt_limit = val;
-               break;
-       case VLOCK_DELTA_LIMIT:
-               vlock_delta_limit = val;
-               break;
-       case VLOCK_DEBUG:
-               vlock_debug = val;
-               break;
-       case VLOCK_DYNAMIC_ADJUST:
-               vlock_dynamic_adjust = val;
-               break;
-       case VLOCK_DIS_CNT_NO_VF_LIMIT:
-               vlock_dis_cnt_no_vf_limit = val;
-               break;
-       default:
-               pr_info("%s:unknown vlock param:%d\n", __func__, sel);
-               break;
-       }
-
-}
-void vlock_status(void)
-{
-       pr_info("\n current vlock parameters status:\n");
-       pr_info("vlock_mode:%d\n", vlock_mode);
-       pr_info("vlock_en:%d\n", vlock_en);
-       pr_info("vlock_adapt:%d\n", vlock_adapt);
-       pr_info("vlock_dis_cnt_limit:%d\n", vlock_dis_cnt_limit);
-       pr_info("vlock_delta_limit:%d\n", vlock_delta_limit);
-       pr_info("vlock_debug:0x%x\n", vlock_debug);
-       pr_info("vlock_dynamic_adjust:%d\n", vlock_dynamic_adjust);
-       pr_info("vlock_state:%d\n", vlock_state);
-       pr_info("vlock_sync_limit_flag:%d\n", vlock_sync_limit_flag);
-       pr_info("pre_vmode:%d\n", pre_vmode);
-       pr_info("pre_hiu_reg_m:0x%x\n", pre_hiu_reg_m);
-       pr_info("pre_hiu_reg_frac:0x%x\n", pre_hiu_reg_frac);
-       pr_info("vlock_dis_cnt:%d\n", vlock_dis_cnt);
-       pr_info("pre_vout_mode:%s\n", pre_vout_mode);
-       pr_info("vlock_dis_cnt_no_vf:%d\n", vlock_dis_cnt_no_vf);
-       pr_info("vlock_dis_cnt_no_vf_limit:%d\n", vlock_dis_cnt_no_vf_limit);
-}
-void vlock_reg_dump(void)
-{
-       unsigned int addr;
-
-       pr_info("----dump vlock reg----\n");
-       for (addr = (0x3000); addr <= (0x3020); addr++)
-               pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
-                       (0xd0100000+(addr<<2)), addr,
-                       READ_VPP_REG(addr));
-}
-/*video lock end*/
-
 /* sharpness process begin */
 void sharpness_process(struct vframe_s *vf)
 {
index 2719cdf..53cb6d1 100644 (file)
@@ -56,19 +56,6 @@ struct ve_regs_s {
        unsigned int mode:1;
        unsigned int rsv:5;
 };
-enum vlock_param_e {
-       VLOCK_EN = 0x0,
-       VLOCK_ADAPT,
-       VLOCK_MODE,
-       VLOCK_DIS_CNT_LIMIT,
-       VLOCK_DELTA_LIMIT,
-       VLOCK_DEBUG,
-       VLOCK_DYNAMIC_ADJUST,
-       VLOCK_STATE,
-       VLOCK_SYNC_LIMIT_FLAG,
-       VLOCK_DIS_CNT_NO_VF_LIMIT,
-       VLOCK_PARAM_MAX,
-};
 
 extern struct ve_hist_s video_ve_hist;
 extern unsigned int ve_size;
@@ -126,17 +113,6 @@ extern void amvecm_color_process(signed int sat_val,
        signed int hue_val, struct vframe_s *vf);
 extern void amvecm_3d_black_process(void);
 extern void amvecm_3d_sync_process(void);
-extern void amve_vlock_process(struct vframe_s *vf);
-extern void amve_vlock_resume(void);
-extern void vlock_param_set(unsigned int val, enum vlock_param_e sel);
-extern void vlock_status(void);
-extern void vlock_reg_dump(void);
-extern void vlock_log_start(void);
-extern void vlock_log_stop(void);
-extern void vlock_log_print(void);
-
-int amvecm_hiu_reg_read(unsigned int reg, unsigned int *val);
-int amvecm_hiu_reg_write(unsigned int reg, unsigned int val);
 extern unsigned int vecm_latch_flag;
 extern unsigned int cm_size;
 extern unsigned int sync_3d_h_start;
@@ -148,7 +124,6 @@ extern unsigned int sync_3d_out_inv;
 extern unsigned int sync_3d_black_color;
 extern unsigned int sync_3d_sync_to_vbo;
 
-extern void __iomem *amvecm_hiu_reg_base;
 
 #ifndef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
 #define VSYNC_WR_MPEG_REG(adr, val) WRITE_VPP_REG(adr, val)
@@ -162,23 +137,6 @@ extern int VSYNC_WR_MPEG_REG(u32 adr, u32 val);
 /* unsigned long long ve_get_vs_cnt(void); */
 /* #endif */
 extern int video_rgb_ogo_xvy_mtx;
-
-#define VLOCK_STATE_NULL 0
-#define VLOCK_STATE_ENABLE_STEP1_DONE 1
-#define VLOCK_STATE_ENABLE_STEP2_DONE 2
-#define VLOCK_STATE_DISABLE_STEP1_DONE 3
-#define VLOCK_STATE_DISABLE_STEP2_DONE 4
-#define VLOCK_STATE_ENABLE_FORCE_RESET 5
-
-/* video lock */
-#define VLOCK_MODE_ENC         0
-#define VLOCK_MODE_AUTO_PLL    1
-#define VLOCK_MODE_MANUAL_PLL  2
-#define XTAL_VLOCK_CLOCK   24000000/*vlock use xtal clock*/
-
-/* 0:enc;1:pll;2:manual pll */
-extern unsigned int vlock_mode;
-extern unsigned int vlock_en;
 extern unsigned int dnlp_sel;
 extern void ve_dnlp_load_reg(void);
 
index 2f5fe47..bf3beef 100644 (file)
@@ -57,6 +57,7 @@
 #include "bitdepth.h"
 #include <linux/amlogic/media/amdolbyvision/dolby_vision.h>
 #include "dnlp_cal.h"
+#include "vlock.h"
 
 #define pr_amvecm_dbg(fmt, args...)\
        do {\
@@ -526,6 +527,8 @@ static ssize_t amvecm_vlock_show(struct class *cla,
        len += sprintf(buf+len,
                "echo vlock_dis_cnt_no_vf_limit val(D) > /sys/class/amvecm/vlock\n");
        len += sprintf(buf+len,
+               "echo vlock_line_limit val(D) > /sys/class/amvecm/vlock\n");
+       len += sprintf(buf+len,
                "echo enable > /sys/class/amvecm/vlock\n");
        len += sprintf(buf+len,
                "echo disable > /sys/class/amvecm/vlock\n");
@@ -597,11 +600,21 @@ static ssize_t amvecm_vlock_store(struct class *cla,
                        return -EINVAL;
                temp_val = val;
                sel = VLOCK_DYNAMIC_ADJUST;
+       } else if (!strncmp(parm[0], "vlock_line_limit", 17)) {
+               if (kstrtol(parm[1], 10, &val) < 0)
+                       return -EINVAL;
+               temp_val = val;
+               sel = VLOCK_LINE_LIMIT;
        } else if (!strncmp(parm[0], "vlock_dis_cnt_no_vf_limit", 25)) {
                if (kstrtol(parm[1], 10, &val) < 0)
                        return -EINVAL;
                temp_val = val;
                sel = VLOCK_DIS_CNT_NO_VF_LIMIT;
+       } else if (!strncmp(parm[0], "vlock_line_limit", 16)) {
+               if (kstrtol(parm[1], 10, &val) < 0)
+                       return -EINVAL;
+               temp_val = val;
+               sel = VLOCK_LINE_LIMIT;
        } else if (!strncmp(parm[0], "enable", 6)) {
                vecm_latch_flag |= FLAG_VLOCK_EN;
        } else if (!strncmp(parm[0], "disable", 7)) {
@@ -4598,9 +4611,17 @@ static int aml_vecm_probe(struct platform_device *pdev)
        /*config vlock mode*/
        /*todo:txlx & g9tv support auto pll,*/
        /*but support not good,need vlsi support optimize*/
-       if (is_meson_txlx_cpu() || is_meson_txhd_cpu())
+       if (is_meson_txhd_cpu())
                vlock_mode = VLOCK_MODE_MANUAL_PLL;
-       else
+       else if (is_meson_txlx_cpu() && !is_meson_txlx_package_962E()) {
+               struct vinfo_s *vinfo = get_current_vinfo();
+
+               if (vinfo->width > 1920)
+                       vlock_mode = VLOCK_MODE_MANUAL_PLL;
+               else
+                       vlock_mode = VLOCK_MODE_MANUAL_SOFT_ENC;
+
+       } else
                vlock_mode = VLOCK_MODE_MANUAL_PLL;
        if (is_meson_gxtvbb_cpu() ||
                is_meson_txl_cpu() || is_meson_txlx_cpu()
index f1df988..d06b472 100644 (file)
 
 #include <linux/amlogic/media/amvecm/cm.h>
 
-/* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) */
-/* TV_ENC_LCD720x480 */
-static struct am_regs_s vlock_enc_lcd720x480 = {
+static struct am_regs_s vlock_enc_setting = {
        20,
        {
        /* optimize */
-       {REG_TYPE_VCBUS, 0x3000,     0xffffffff, 0xE0f50f1b  },
+       {REG_TYPE_VCBUS, 0x3000,     0xffffffff, 0xE3f50f10  },
        {REG_TYPE_VCBUS, 0x3001,     0xffffffff, 0x41E3c3c   },
        {REG_TYPE_VCBUS, 0x3002,     0xffffffff, 0x6000000   },
-       {REG_TYPE_VCBUS, 0x3003,     0xffffffff, 0x40280280  },
+       {REG_TYPE_VCBUS, 0x3003,     0xffffffff, 0x20680680  },
        {REG_TYPE_VCBUS, 0x3004,     0xffffffff, 0x280280    },
        {REG_TYPE_VCBUS, 0x3005,     0xffffffff, 0x8020000   },
        {REG_TYPE_VCBUS, 0x3006,     0xffffffff, 0x0008000   },
-       {REG_TYPE_VCBUS, 0x3007,     0xffffffff, 0x6000000   },
-       {REG_TYPE_VCBUS, 0x3008,     0xffffffff, 0x6000000   },
+       {REG_TYPE_VCBUS, 0x3007,     0xffffffff, 0x0000000   },
+       {REG_TYPE_VCBUS, 0x3008,     0xffffffff, 0x0000000   },
        {REG_TYPE_VCBUS, 0x3009,     0xffffffff, 0x0008000   },
        {REG_TYPE_VCBUS, 0x300a,     0xffffffff, 0x8000000   },
-       {REG_TYPE_VCBUS, 0x300b,     0xffffffff, 0x0008000   },
+       {REG_TYPE_VCBUS, 0x300b,     0xffffffff, 0x000a000   },
        {REG_TYPE_VCBUS, 0x300c,     0xffffffff, 0xa000000   },
        {REG_TYPE_VCBUS, 0x300d,     0xffffffff, 0x0004000   },
        {REG_TYPE_VCBUS, 0x3010,     0xffffffff, 0x20001000  },
@@ -49,22 +47,21 @@ static struct am_regs_s vlock_enc_lcd720x480 = {
        {0}
        }
 };
-/* out:TV_ENC_LCD1920x1080P60;in:50hz pal av */
-static struct am_regs_s vlock_pll_in50hz_out60hz = {
+static struct am_regs_s vlock_pll_setting = {
        20,
        {
        /* optimize */
-       {REG_TYPE_VCBUS, 0x3000,     0xffffffff, 0x07f13f1b   },
+       {REG_TYPE_VCBUS, 0x3000,     0xffffffff, 0x07f13f1a   },
        {REG_TYPE_VCBUS, 0x3001,     0xffffffff, 0x04053c32   },
        {REG_TYPE_VCBUS, 0x3002,     0xffffffff, 0x06000000   },
-       {REG_TYPE_VCBUS, 0x3003,     0xffffffff, 0x20680680   },
+       {REG_TYPE_VCBUS, 0x3003,     0xffffffff, 0x20780780   },
        {REG_TYPE_VCBUS, 0x3004,     0xffffffff, 0x00000000   },
        {REG_TYPE_VCBUS, 0x3005,     0xffffffff, 0x00080000   },
        {REG_TYPE_VCBUS, 0x3006,     0xffffffff, 0x00070000   },
        {REG_TYPE_VCBUS, 0x3007,     0xffffffff, 0x00000000   },
        {REG_TYPE_VCBUS, 0x3008,     0xffffffff, 0x00000000   },
        {REG_TYPE_VCBUS, 0x3009,     0xffffffff, 0x00100000   },
-       {REG_TYPE_VCBUS, 0x300a,     0xffffffff, 0x00004000   },
+       {REG_TYPE_VCBUS, 0x300a,     0xffffffff, 0x00008000   },
        {REG_TYPE_VCBUS, 0x300b,     0xffffffff, 0x00100000   },
        {REG_TYPE_VCBUS, 0x300c,     0xffffffff, 0x00000000   },
        {REG_TYPE_VCBUS, 0x300d,     0xffffffff, 0x00004000   },
@@ -78,7 +75,5 @@ static struct am_regs_s vlock_pll_in50hz_out60hz = {
        }
 };
 
-/* #endif */
-
 #endif
 
index 3de8fc9..6c99920 100644 (file)
 #define HHI_HDMI_PLL_CNTL2                         0x10c9
 #define HHI_VID_LOCK_CLK_CNTL                  0x10f2
 #define HHI_HDMI_PLL_CNTL6                         0x10cd
+/* for vlock enc mode adjust begin */
+#define ENCL_VIDEO_MAX_LNCNT            0x1cbb
+#define ENCL_VIDEO_MAX_PXCNT 0x1cb0
 #define ENCL_MAX_LINE_SWITCH_POINT             0x1cc8
-/* #define P_ENCL_MAX_LINE_SWITCH_POINT */
-/* VCBUS_REG_ADDR(ENCL_MAX_LINE_SWITCH_POINT) */
+#define ENCL_VIDEO_MODE 0x1ca7
+#define ENCL_VIDEO_MODE_ADV 0x1ca8
+
+#define ENCP_VIDEO_MAX_LNCNT 0x1bae
+#define ENCP_VIDEO_MAX_PXCNT 0x1b97
+#define ENCP_VIDEO_MODE 0x1b8d
+#define ENCP_MAX_LINE_SWITCH_POINT 0x1c0f
+
+#define ENCT_VIDEO_MAX_LNCNT 0x1c7b
+#define ENCT_VIDEO_MAX_PXCNT 0x1c70
+#define ENCT_VIDEO_MODE 0x1c67
+#define ENCT_MAX_LINE_SWITCH_POINT 0x1c88
+/* for vlock enc mode adjust end */
+
 #define HHI_VID_LOCK_CLK_CNTL                  0x10f2
 
-#define ENCL_VIDEO_MAX_LNCNT            0x1cbb
 #define VDIN_MEAS_VS_COUNT_LO 0x125c
 /*after GXL new add CNTL1,same with CNTL2 on G9TV/GXTVBB*/
 #define HHI_HDMI_PLL_CNTL1                         0x10c9
diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.c b/drivers/amlogic/media/enhancement/amvecm/vlock.c
new file mode 100644 (file)
index 0000000..14b8e4a
--- /dev/null
@@ -0,0 +1,1111 @@
+/*
+ * drivers/amlogic/media/enhancement/amvecm/vlock.c
+ *
+ * Copyright (C) 2017 Amlogic, Inc. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/spinlock.h>
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/amlogic/cpu_version.h>
+#include <linux/amlogic/media/vfm/vframe.h>
+#include <linux/amlogic/media/amvecm/amvecm.h>
+#include <linux/amlogic/media/vout/vinfo.h>
+#include <linux/amlogic/media/vout/vout_notify.h>
+#include <linux/io.h>
+#include "arch/vpp_regs.h"
+#include "vlock.h"
+#include "amvecm_vlock_regmap.h"
+#include "amcm.h"
+
+/* video lock */
+/* 0:enc;1:pll;
+ * 2:manual pll;
+ * 3:manual_enc mode(only support lvds/vx1)
+ */
+unsigned int vlock_mode = VLOCK_MODE_MANUAL_PLL;
+unsigned int vlock_en = 1;
+/*
+ *0:only support 50->50;60->60;24->24;30->30;
+ *1:support 24/30/50/60/100/120 mix,such as 50->60;
+ */
+static unsigned int vlock_adapt;
+static unsigned int vlock_dis_cnt_limit = 2;
+static unsigned int vlock_delta_limit = 2;
+/* [reg(0x3009) x linemax_num)]>>24 is the limit line of enc mode */
+static signed int vlock_line_limit = 4;
+/* 0x3009 default setting for 2 line(1080p-output) is 0x8000 */
+static unsigned int vlock_capture_limit = 0x8000;
+static unsigned int vlock_debug;
+static unsigned int vlock_dynamic_adjust = 1;
+
+static unsigned int vlock_sync_limit_flag;
+static unsigned int vlock_state = VLOCK_STATE_NULL;/*1/2/3:vlock step*/
+static enum vmode_e pre_vmode = VMODE_INIT_NULL;
+static enum vframe_source_type_e pre_source_type =
+               VFRAME_SOURCE_TYPE_OTHERS;
+static enum vframe_source_mode_e pre_source_mode =
+               VFRAME_SOURCE_MODE_OTHERS;
+static unsigned int pre_input_freq;
+static unsigned int pre_output_freq;
+static unsigned int vlock_dis_cnt;
+static char pre_vout_mode[64];
+static bool vlock_vmode_changed;
+static unsigned int pre_hiu_reg_m;
+static unsigned int pre_hiu_reg_frac;
+static signed int pre_enc_max_line;
+static signed int pre_enc_max_pixel;
+static unsigned int enc_max_line_addr;
+static unsigned int enc_max_pixel_addr;
+static unsigned int enc_video_mode_addr;
+static unsigned int enc_video_mode_adv_addr;
+static unsigned int enc_max_line_switch_addr;
+
+static unsigned int vlock_dis_cnt_no_vf;
+static unsigned int vlock_dis_cnt_no_vf_limit = 5;
+
+static unsigned int vlock_log_cnt;/*cnt base: vlock_log_s*/
+static unsigned int vlock_log_size = 60;/*size base: vlock_log_s*/
+static unsigned int vlock_log_delta_frac = 100;
+static unsigned int vlock_log_delta_ivcnt = 0xff;
+static unsigned int vlock_log_delta_ovcnt = 0xff;
+static unsigned int vlock_log_delta_vcnt = 0xff;
+static unsigned int vlock_log_last_ivcnt;
+static unsigned int vlock_log_last_ovcnt;
+static unsigned int vlock_log_delta_m;
+static unsigned int vlock_log_delta_en;
+module_param(vlock_log_size, uint, 0664);
+MODULE_PARM_DESC(vlock_log_size, "\n vlock_log_size\n");
+module_param(vlock_log_cnt, uint, 0664);
+MODULE_PARM_DESC(vlock_log_cnt, "\n vlock_log_cnt\n");
+module_param(vlock_log_delta_frac, uint, 0664);
+MODULE_PARM_DESC(vlock_log_delta_frac, "\n vlock_log_delta_frac\n");
+module_param(vlock_log_delta_m, uint, 0664);
+MODULE_PARM_DESC(vlock_log_delta_m, "\n vlock_log_delta_m\n");
+module_param(vlock_log_delta_en, uint, 0664);
+MODULE_PARM_DESC(vlock_log_delta_en, "\n vlock_log_delta_en\n");
+
+module_param(vlock_log_delta_ivcnt, uint, 0664);
+MODULE_PARM_DESC(vlock_log_delta_ivcnt, "\n vlock_log_delta_ivcnt\n");
+
+module_param(vlock_log_delta_ovcnt, uint, 0664);
+MODULE_PARM_DESC(vlock_log_delta_ovcnt, "\n vlock_log_delta_ovcnt\n");
+
+module_param(vlock_log_delta_vcnt, uint, 0664);
+MODULE_PARM_DESC(vlock_log_delta_vcnt, "\n vlock_log_delta_vcnt\n");
+
+static unsigned int vlock_frac;
+module_param(vlock_frac, uint, 0664);
+MODULE_PARM_DESC(vlock_frac, "\n vlock_frac\n");
+static unsigned int vlock_frac_delta;
+module_param(vlock_frac_delta, uint, 0664);
+MODULE_PARM_DESC(vlock_frac_delta, "\n vlock_frac_delta\n");
+
+static unsigned int vlock_latch_en_cnt = 20;
+module_param(vlock_latch_en_cnt, uint, 0664);
+MODULE_PARM_DESC(vlock_latch_en_cnt, "\n vlock_latch_en_cnt\n");
+
+static unsigned int vlock_log_en;
+struct vlock_log_s **vlock_log;
+
+static signed int err_accum;
+static unsigned int last_i_vsync;
+
+int amvecm_hiu_reg_read(unsigned int reg, unsigned int *val)
+{
+       *val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2));
+       return 0;
+}
+
+int amvecm_hiu_reg_write(unsigned int reg, unsigned int val)
+{
+       writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2)));
+       return 0;
+}
+static int amvecm_hiu_reg_write_bits(unsigned int reg, unsigned int value,
+               unsigned int start, unsigned int len)
+{
+       unsigned int rd_val;
+
+       amvecm_hiu_reg_read(reg, &rd_val);
+       amvecm_hiu_reg_write(reg, ((rd_val &
+            ~(((1L << (len)) - 1) << (start))) |
+           (((value) & ((1L << (len)) - 1)) << (start))));
+       return 0;
+}
+
+
+static unsigned int vlock_check_input_hz(struct vframe_s *vf)
+{
+       unsigned int ret_hz = 0;
+       unsigned int duration = vf->duration;
+
+       if ((vf->source_type != VFRAME_SOURCE_TYPE_CVBS) &&
+               (vf->source_type != VFRAME_SOURCE_TYPE_HDMI))
+               ret_hz = 0;
+       else if (vf->source_type == VFRAME_SOURCE_TYPE_HDMI) {
+               if (duration != 0)
+                       ret_hz = (96000 + duration/2)/duration;
+       } else if (vf->source_type == VFRAME_SOURCE_TYPE_CVBS) {
+               if (vf->source_mode == VFRAME_SOURCE_MODE_NTSC)
+                       ret_hz = 60;
+               else if ((vf->source_mode == VFRAME_SOURCE_MODE_PAL) ||
+                       (vf->source_mode == VFRAME_SOURCE_MODE_SECAM))
+                       ret_hz = 50;
+               else
+                       ret_hz = 0;
+       }
+       return ret_hz;
+}
+
+static unsigned int vlock_check_output_hz(unsigned int sync_duration_num)
+{
+       unsigned int ret_hz = 0;
+
+       switch (sync_duration_num) {
+       case 24:
+               ret_hz = 24;
+               break;
+       case 30:
+               ret_hz = 30;
+               break;
+       case 50:
+               ret_hz = 50;
+               break;
+       case 60:
+               ret_hz = 60;
+               break;
+       case 100:
+               ret_hz = 100;
+               break;
+       case 120:
+               ret_hz = 120;
+               break;
+       default:
+               ret_hz = 0;
+               break;
+       }
+       return ret_hz;
+}
+/*vlock is support eq_after gxbb,but which is useful only for tv chip
+ *after gxl,the enable/disable reg_bit is changed
+ */
+static void vlock_enable(bool enable)
+{
+       unsigned int tmp_value;
+
+       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
+
+       if (is_meson_gxtvbb_cpu()) {
+               if (vlock_mode == VLOCK_MODE_MANUAL_PLL) {
+                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 20, 1);
+                       /*vlsi suggest config:don't enable load signal,
+                        *on gxtvbb this load signal will effect SSG,
+                        *which may result in flashes black
+                        */
+                       if (is_meson_gxtvbb_cpu() &&
+                               (((tmp_value >> 21) & 0x3) != 2))
+                               amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6,
+                                       2, 21, 2);
+               } else
+                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6,
+                               enable, 20, 1);
+       } else if (is_meson_txl_cpu() || is_meson_txlx_cpu()) {
+               if (vlock_mode == VLOCK_MODE_MANUAL_PLL)
+                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5, 0, 3, 1);
+               else
+                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5,
+                               enable, 3, 1);
+       }
+}
+static void vlock_setting(struct vframe_s *vf,
+               unsigned int input_hz, unsigned int output_hz)
+{
+       unsigned int freq_hz = 0, hiu_reg_value_2_addr = HHI_HDMI_PLL_CNTL2;
+       unsigned int reg_value = 0, hiu_reg_value, hiu_reg_value_2;
+       unsigned int hiu_m_val, hiu_frac_val, temp_value;
+
+       amvecm_hiu_reg_write(HHI_VID_LOCK_CLK_CNTL, 0x80);
+       if ((vlock_mode == VLOCK_MODE_AUTO_ENC) ||
+               (vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
+               (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+               if ((vlock_debug & VLOCK_DEBUG_FLUSH_REG_DIS) == 0)
+                       am_set_regmap(&vlock_enc_setting);
+               /*vlock line limit*/
+               WRITE_VPP_REG(VPU_VLOCK_OUTPUT0_CAPT_LMT, vlock_capture_limit);
+               /* VLOCK_CNTL_EN disable */
+               vlock_enable(0);
+               /* disable to adjust pll */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 29, 1);
+               /* CFG_VID_LOCK_ADJ_EN enable */
+               if ((vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
+                       (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+                       /*auto vlock off*/
+                       WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
+                               0, 13, 1);
+                       WRITE_VPP_REG_BITS(enc_video_mode_adv_addr, 1, 14, 1);
+               } else {
+                       WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
+                               1, 13, 1);
+                       WRITE_VPP_REG_BITS(enc_video_mode_adv_addr, 0, 14, 1);
+               }
+               /* enable to adjust pll */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 30, 1);
+               /*clear accum1 value*/
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+               /*clear accum0 value*/
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+               /*@20180314 new add*/
+               /*
+                *set input & output freq
+                *bit0~7:input freq
+                *bit8~15:output freq
+                */
+               if ((vf->type_original & VIDTYPE_TYPEMASK) &&
+                       (vlock_mode != VLOCK_MODE_MANUAL_SOFT_ENC))
+                       input_hz = input_hz >> 1;
+               freq_hz = input_hz | (output_hz << 8);
+               WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16);
+               /*
+                *Ifrm_cnt_mod:0x3001(bit23~16);
+                *(output_freq/input_freq)*Ifrm_cnt_mod must be integer
+                */
+               if (vlock_adapt == 0)
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, 1, 16, 8);
+               else
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
+                               input_hz, 16, 8);
+               temp_value = READ_VPP_REG(enc_max_line_addr);
+               WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX, temp_value, 0, 14);
+               temp_value = READ_VPP_REG(enc_max_pixel_addr);
+               WRITE_VPP_REG_BITS(VPU_VLOCK_OROW_OCOL_MAX, temp_value, 16, 14);
+               WRITE_VPP_REG_BITS(VPU_VLOCK_ADJ_EN_SYNC_CTRL,
+                       vlock_latch_en_cnt, 8, 8);
+               WRITE_VPP_REG_BITS(enc_video_mode_addr, 0, 15, 1);
+       }
+       if ((vlock_mode == VLOCK_MODE_AUTO_PLL) ||
+               (vlock_mode == VLOCK_MODE_MANUAL_PLL)) {
+               /* av pal in,1080p60 hdmi out as default */
+               if ((vlock_debug & VLOCK_DEBUG_FLUSH_REG_DIS) == 0)
+                       am_set_regmap(&vlock_pll_setting);
+               /*
+                *set input & output freq
+                *bit0~7:input freq
+                *bit8~15:output freq
+                */
+               if (vf->type_original & VIDTYPE_TYPEMASK)
+                       input_hz = input_hz >> 1;
+               freq_hz = input_hz | (output_hz << 8);
+               WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16);
+               /*
+                *Ifrm_cnt_mod:0x3001(bit23~16);
+                *(output_freq/input_freq)*Ifrm_cnt_mod must be integer
+                */
+               if (vlock_adapt == 0)
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, 1, 16, 8);
+               else
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
+                               input_hz, 16, 8);
+               /*set PLL M_INT;PLL M_frac*/
+               /* WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, */
+               /* READ_CBUS_REG_BITS(HHI_HDMI_PLL_CNTL,0,9),12,9); */
+               amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &hiu_reg_value);
+               amvecm_hiu_reg_read(hiu_reg_value_2_addr,
+                       &hiu_reg_value_2);
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) {
+                       hiu_m_val = hiu_reg_value & 0x1FF;
+                       hiu_frac_val = hiu_reg_value_2 & 0x3FF;
+                       if (hiu_reg_value_2 & 0x800) {
+                               hiu_m_val -= 1;
+                               if (hiu_reg_value_2 & 0x400)
+                                       hiu_m_val -= 1;
+                               hiu_frac_val = 0x400 -
+                                       ((~(hiu_frac_val - 1)) & 0x3ff);
+                       } else if (hiu_reg_value_2 & 0x400) {
+                               hiu_m_val += 1;
+                       }
+                       reg_value = (hiu_m_val << 12)
+                               + (hiu_frac_val << 2);
+               }
+               WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, reg_value, 0, 21);
+
+               /*enable vlock to adj pll*/
+               /* CFG_VID_LOCK_ADJ_EN disable */
+               WRITE_VPP_REG_BITS(ENCL_MAX_LINE_SWITCH_POINT, 0, 13, 1);
+               /* disable to adjust pll */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 30, 1);
+               /* VLOCK_CNTL_EN enable */
+               vlock_enable(1);
+               /* enable to adjust pll */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 29, 1);
+       }
+       /* vlock module output goes to which module */
+       switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL, 0, 2)) {
+       case 0:/* ENCL */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 26, 2);
+               break;
+       case 1:/* ENCI */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 2, 26, 2);
+               break;
+       case 2: /* ENCP */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 26, 2);
+               break;
+       default:
+               break;
+       }
+       if ((vf->source_type == VFRAME_SOURCE_TYPE_TUNER) ||
+               (vf->source_type == VFRAME_SOURCE_TYPE_CVBS))
+               /* Input Vsync source select from tv-decoder */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 2, 16, 3);
+       else if (vf->source_type == VFRAME_SOURCE_TYPE_HDMI)
+               /* Input Vsync source select from hdmi-rx */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 16, 3);
+       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 31, 1);
+}
+void vlock_vmode_check(void)
+{
+       const struct vinfo_s *vinfo;
+       unsigned int tmp_value, hiu_reg_addr;
+       char cur_vout_mode[64];
+
+       if (vlock_en == 0)
+               return;
+       if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
+               hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
+       else
+               hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
+       vinfo = get_current_vinfo();
+       vlock_vmode_changed = 0;
+       memset(cur_vout_mode, 0, sizeof(cur_vout_mode));
+       strcpy(cur_vout_mode, vinfo->name);
+       if (strcmp(cur_vout_mode, pre_vout_mode) != 0) {
+               if ((vlock_mode == VLOCK_MODE_MANUAL_PLL) ||
+                       (vlock_mode == VLOCK_MODE_AUTO_PLL)) {
+                       amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
+                       pre_hiu_reg_frac = tmp_value & 0xfff;
+                       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
+                       pre_hiu_reg_m = tmp_value & 0x1ff;
+               }
+               if ((vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
+                       (vlock_mode == VLOCK_MODE_AUTO_ENC) ||
+                       (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+                       switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL,
+                               0, 2)) {
+                       case 0:
+                               enc_max_line_addr = ENCL_VIDEO_MAX_LNCNT;
+                               enc_max_pixel_addr = ENCL_VIDEO_MAX_PXCNT;
+                               enc_video_mode_addr = ENCL_VIDEO_MODE;
+                               enc_video_mode_adv_addr = ENCL_VIDEO_MODE_ADV;
+                               enc_max_line_switch_addr =
+                                       ENCL_MAX_LINE_SWITCH_POINT;
+                               break;
+                       #if 0 /*enc mode not adapt to ENCP and ENCT*/
+                       case 2:
+                               enc_max_line_addr = ENCP_VIDEO_MAX_LNCNT;
+                               enc_max_pixel_addr = ENCP_VIDEO_MAX_PXCNT;
+                               enc_video_mode_addr = ENCP_VIDEO_MODE;
+                               enc_max_line_switch_addr =
+                                       ENCP_MAX_LINE_SWITCH_POINT;
+                               break;
+                       case 3:
+                               enc_max_line_addr = ENCT_VIDEO_MAX_LNCNT;
+                               enc_max_pixel_addr = ENCT_VIDEO_MAX_PXCNT;
+                               enc_video_mode_addr = ENCT_VIDEO_MODE;
+                               enc_max_line_switch_addr =
+                                       ENCT_MAX_LINE_SWITCH_POINT;
+                               break;
+                       #endif
+                       default:
+                               enc_max_line_addr = ENCL_VIDEO_MAX_LNCNT;
+                               enc_max_pixel_addr = ENCL_VIDEO_MAX_PXCNT;
+                               enc_video_mode_addr = ENCL_VIDEO_MODE;
+                               enc_video_mode_adv_addr = ENCL_VIDEO_MODE_ADV;
+                               enc_max_line_switch_addr =
+                                       ENCL_MAX_LINE_SWITCH_POINT;
+                               break;
+                       }
+                       pre_enc_max_line = READ_VPP_REG(enc_max_line_addr);
+                       pre_enc_max_pixel = READ_VPP_REG(enc_max_pixel_addr);
+                       vlock_capture_limit = ((1 << 12) * vlock_line_limit) /
+                               vinfo->vtotal + 1;
+                       vlock_capture_limit <<= 12;
+               }
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("[%s]:vout mode changed:%s==>%s\n",
+                               __func__, pre_vout_mode, cur_vout_mode);
+               memset(pre_vout_mode, 0, sizeof(pre_vout_mode));
+               strcpy(pre_vout_mode, cur_vout_mode);
+               vlock_vmode_changed = 1;
+       }
+}
+static void vlock_disable_step1(void)
+{
+       unsigned int m_reg_value, tmp_value, enc_max_line, enc_max_pixel;
+       unsigned int hiu_reg_addr;
+
+       /* VLOCK_CNTL_EN disable */
+       vlock_enable(0);
+       vlock_vmode_check();
+       if ((vlock_mode == VLOCK_MODE_MANUAL_PLL) ||
+                       (vlock_mode == VLOCK_MODE_AUTO_PLL)) {
+               if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
+                       hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
+               else
+                       hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
+               amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
+               m_reg_value = tmp_value & 0xfff;
+               if ((m_reg_value != pre_hiu_reg_frac) &&
+                       (pre_hiu_reg_m != 0)) {
+                       tmp_value = (tmp_value & 0xfffff000) |
+                               (pre_hiu_reg_frac & 0xfff);
+                       amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
+               }
+               amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
+               m_reg_value = tmp_value & 0x1ff;
+               if ((m_reg_value != pre_hiu_reg_m) &&
+                       (pre_hiu_reg_m != 0)) {
+                       tmp_value = (tmp_value & 0xfffffe00) |
+                               (pre_hiu_reg_m & 0x1ff);
+                       amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
+               }
+       }
+       if ((vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
+               (vlock_mode == VLOCK_MODE_AUTO_ENC) ||
+               (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+               err_accum = 0;
+               WRITE_VPP_REG_BITS(enc_video_mode_adv_addr, 0, 14, 1);
+               enc_max_line = READ_VPP_REG(enc_max_line_addr);
+               enc_max_pixel = READ_VPP_REG(enc_max_pixel_addr);
+               if (!(vlock_debug & VLOCK_DEBUG_ENC_LINE_ADJ_DIS) &&
+                       (enc_max_line != pre_enc_max_line) &&
+                       (pre_enc_max_line != 0) && (enc_max_line_addr != 0))
+                       WRITE_VPP_REG(enc_max_line_addr, pre_enc_max_line);
+               if (!(vlock_debug & VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS) &&
+                       (enc_max_pixel != pre_enc_max_pixel) &&
+                       (enc_max_line_addr != 0) && (enc_max_pixel_addr != 0)) {
+                       WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
+                               0x1fff, 0, 13);
+                       WRITE_VPP_REG(enc_max_pixel_addr, pre_enc_max_pixel);
+               }
+       }
+       vlock_dis_cnt = vlock_dis_cnt_limit;
+       memset(pre_vout_mode, 0, sizeof(pre_vout_mode));
+       pre_vmode = VMODE_INIT_NULL;
+       pre_source_type = VFRAME_SOURCE_TYPE_OTHERS;
+       pre_source_mode = VFRAME_SOURCE_MODE_OTHERS;
+       pre_input_freq = 0;
+       pre_output_freq = 0;
+       vlock_state = VLOCK_STATE_DISABLE_STEP1_DONE;
+}
+
+static void vlock_disable_step2(void)
+{
+       unsigned int temp_val;
+       /* need delay to disable follow regs(vlsi suggest!!!) */
+       if (vlock_dis_cnt > 0)
+               vlock_dis_cnt--;
+       if (vlock_dis_cnt == 0) {
+               /* disable to adjust pll */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 29, 1);
+               /* CFG_VID_LOCK_ADJ_EN disable */
+               WRITE_VPP_REG_BITS(ENCL_MAX_LINE_SWITCH_POINT,
+                               0, 13, 1);
+               /* disable to adjust pll */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 30, 1);
+               /* disable vid_lock_en */
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 31, 1);
+               vlock_state = VLOCK_STATE_DISABLE_STEP2_DONE;
+               amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val);
+               if (is_meson_gxtvbb_cpu() && (((temp_val >> 21) & 0x3) != 0))
+                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 21, 2);
+       }
+}
+static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo,
+       unsigned int input_hz, unsigned int output_hz)
+{
+       vlock_setting(vf, input_hz, output_hz);
+       if (vlock_debug & VLOCK_DEBUG_INFO) {
+               pr_info("%s:vmode/source_type/source_mode/input_freq/output_freq:\n",
+                       __func__);
+               pr_info("\t%d/%d/%d/%d/%d=>%d/%d/%d/%d/%d\n",
+                       pre_vmode, pre_source_type, pre_source_mode,
+                       pre_input_freq, pre_output_freq,
+                       vinfo->mode, vf->source_type, vf->source_mode,
+                       input_hz, output_hz);
+       }
+       pre_vmode = vinfo->mode;
+       pre_source_type = vf->source_type;
+       pre_source_mode = vf->source_mode;
+       pre_input_freq = input_hz;
+       pre_output_freq = output_hz;
+       vlock_sync_limit_flag = 0;
+       vlock_vmode_changed = 0;
+       vlock_dis_cnt = 0;
+       vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
+       vlock_log_cnt = 0;
+}
+
+void vlock_log_start(void)
+{
+       unsigned int i;
+
+       vlock_log = kmalloc_array(vlock_log_size, sizeof(struct vlock_log_s *),
+               GFP_KERNEL);
+       if (vlock_log == NULL)
+               return;
+       for (i = 0; i < vlock_log_size; i++) {
+               vlock_log[i] = kmalloc(sizeof(struct vlock_log_s), GFP_KERNEL);
+               if (vlock_log[i] == NULL) {
+                       pr_info("%s:vlock_log[%d] kmalloc fail!!!\n",
+                               __func__, i);
+                       return;
+               }
+       }
+       vlock_log_en = 1;
+       pr_info("%s done\n", __func__);
+}
+void vlock_log_stop(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < vlock_log_size; i++)
+               kfree(vlock_log[i]);
+       kfree(vlock_log);
+       vlock_log_en = 0;
+       pr_info("%s done\n", __func__);
+}
+void vlock_log_print(void)
+{
+       unsigned int i, j;
+
+       if (vlock_log[0] == NULL)
+               return;
+       for (i = 0; i < vlock_log_size; i++) {
+               pr_info("\n*******[%d]pll_m:0x%x,pll_frac:0x%x*******\n",
+                       i, vlock_log[i]->pll_m, vlock_log[i]->pll_frac);
+               pr_info("*******enc_line_max:0x%x,line_num_adj:%d*******\n",
+                       vlock_log[i]->enc_line_max, vlock_log[i]->line_num_adj);
+               pr_info("*******enc_pixel_max:0x%x,pixel_num_adj:%d*******\n",
+                       vlock_log[i]->enc_pixel_max,
+                       vlock_log[i]->pixel_num_adj);
+               pr_info("*******nT0:%d(0x%x),vdif_err:%d(0x%x),err_sum:%d(0x%x),margin:%d(0x%x)*******\n",
+                       vlock_log[i]->nT0, vlock_log[i]->nT0,
+                       vlock_log[i]->vdif_err, vlock_log[i]->vdif_err,
+                       vlock_log[i]->err_sum, vlock_log[i]->err_sum,
+                       vlock_log[i]->margin, vlock_log[i]->margin);
+               for (j = 0; j < VLOCK_REG_NUM;) {
+                       if ((j%8 == 0) && ((j + 7) < VLOCK_REG_NUM)) {
+                               pr_info("0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\t0x%08x\n",
+                                       vlock_log[i]->vlock_regs[j],
+                                       vlock_log[i]->vlock_regs[j+1],
+                                       vlock_log[i]->vlock_regs[j+2],
+                                       vlock_log[i]->vlock_regs[j+3],
+                                       vlock_log[i]->vlock_regs[j+4],
+                                       vlock_log[i]->vlock_regs[j+5],
+                                       vlock_log[i]->vlock_regs[j+6],
+                                       vlock_log[i]->vlock_regs[j+7]);
+                               j += 8;
+                       } else {
+                               pr_info("0x%08x\t",
+                                       vlock_log[i]->vlock_regs[j]);
+                               j++;
+                       }
+
+               }
+       }
+       pr_info("%s done\n", __func__);
+}
+void vlock_reg_get(void)
+{
+       unsigned int i;
+
+       for (i = 0; i < VLOCK_REG_NUM; i++)
+               vlock_log[vlock_log_cnt]->vlock_regs[i] =
+                       READ_VPP_REG(0x3000 + i);
+}
+static void vlock_enable_step3_enc(void)
+{
+       unsigned int line_num = 0, enc_max_line = 0, polity_line_num = 0;
+       unsigned int pixel_num = 0, enc_max_pixel = 0, polity_pixel_num = 0;
+
+       /*vlock pixel num adjust*/
+       if (!(vlock_debug & VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS)) {
+               polity_pixel_num = READ_VPP_REG_BITS(VPU_VLOCK_RO_LINE_PIX_ADJ,
+                       13, 1);
+               pixel_num = READ_VPP_REG_BITS(VPU_VLOCK_RO_LINE_PIX_ADJ, 0, 14);
+               if (polity_pixel_num) {
+                       pixel_num = (~(pixel_num - 1)) & 0x3fff;
+                       enc_max_pixel = pre_enc_max_pixel - pixel_num;
+               } else {
+                       enc_max_pixel = pre_enc_max_pixel + pixel_num;
+               }
+               if (enc_max_pixel > 0x1fff)
+                       WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
+                               pixel_num, 0, 13);
+               else
+                       WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
+                               enc_max_pixel, 0, 13);
+       }
+       /*vlock line num adjust*/
+       if (!(vlock_debug & VLOCK_DEBUG_ENC_LINE_ADJ_DIS)) {
+               polity_line_num = READ_VPP_REG_BITS(VPU_VLOCK_RO_LINE_PIX_ADJ,
+                       29, 1);
+               line_num = READ_VPP_REG_BITS(VPU_VLOCK_RO_LINE_PIX_ADJ, 16, 14);
+               if (polity_line_num) {
+                       line_num = (~(line_num - 1)) & 0x3fff;
+                       enc_max_line = pre_enc_max_line - line_num;
+               } else {
+                       enc_max_line = pre_enc_max_line + line_num;
+               }
+               if (enc_max_pixel > 0x1fff)
+                       enc_max_line += 1;
+               WRITE_VPP_REG(enc_max_line_addr, enc_max_line);
+       }
+
+       if (vlock_log_en && (vlock_log_cnt < vlock_log_size)) {
+               vlock_log[vlock_log_cnt]->enc_line_max = enc_max_line;
+               vlock_log[vlock_log_cnt]->line_num_adj = line_num;
+               vlock_log[vlock_log_cnt]->enc_pixel_max = enc_max_pixel;
+               vlock_log[vlock_log_cnt]->pixel_num_adj = pixel_num;
+               vlock_reg_get();
+               vlock_log_cnt++;
+       }
+}
+
+static void vlock_enable_step3_soft_enc(void)
+{
+       unsigned int ia, oa;
+       signed int margin;
+       signed int pixel_adj;
+       signed int err, vdif_err;
+       signed int nT0, tfrac;
+       signed int line_adj;
+
+       signed int reg_errclip_rate =
+               READ_VPP_REG_BITS(VPU_VLOCK_LOOP0_CTRL0, 24, 8);
+       signed int reg_accum_lmt = READ_VPP_REG(VPU_VLOCK_LOOP0_ACCUM_LMT);
+       signed int reg_capt_gain =
+               READ_VPP_REG_BITS(VPU_VLOCK_LOOP0_CTRL0, 0, 8);
+       signed int reg_capt_rs =
+               READ_VPP_REG_BITS(VPU_VLOCK_LOOP0_CTRL0, 8, 4);
+       signed int reg_capt_lmt = READ_VPP_REG(VPU_VLOCK_OUTPUT0_CAPT_LMT);
+
+       if (last_i_vsync == 0) {
+               last_i_vsync = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
+               return;
+       }
+       ia = (READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST) + last_i_vsync + 1) / 2;
+       oa = READ_VPP_REG(VPU_VLOCK_RO_VS_O_DIST);
+
+       if (ia < oa)
+               margin = ia >> 8;
+       else
+               margin = oa >> 8;
+
+       margin *= reg_errclip_rate;
+       margin  = (margin >> 26) ? 0x3ffffff : margin;
+       margin  = margin << 5;
+       margin  = (margin >> 28) ? 0xfffffff : margin;
+
+       err = oa - ia;
+
+       if ((err < margin) && (err > -margin))
+               err = err;
+       else
+               err = 0;
+
+       vdif_err = err_accum + err;
+       vdif_err = (vdif_err >  (1<<30)) ?  (1<<30) :
+       (vdif_err < -(1<<30)) ? -(1<<30) : vdif_err;
+
+       err_accum = (vdif_err >  reg_accum_lmt) ?  reg_accum_lmt :
+       (vdif_err < -reg_accum_lmt) ? -reg_accum_lmt : vdif_err;
+
+       nT0 = (err_accum * reg_capt_gain) >> reg_capt_rs;
+
+       nT0 = -nT0;
+
+       nT0 = (nT0 >  reg_capt_lmt) ?  reg_capt_lmt :
+       (nT0 < -reg_capt_lmt) ? -reg_capt_lmt : nT0;
+
+       nT0 = (nT0 * pre_enc_max_line) >> 10;
+
+       line_adj = nT0 >> 14;
+
+       if (line_adj > vlock_line_limit)
+               line_adj = vlock_line_limit;
+       else if (line_adj < -vlock_line_limit)
+               line_adj = -vlock_line_limit;
+
+       tfrac = nT0 - (line_adj << 14);
+
+       pixel_adj = (tfrac * pre_enc_max_pixel + 8192) >> 14;
+
+       if ((pixel_adj + pre_enc_max_pixel) > 0x1fff) {
+               line_adj = line_adj + 1;
+               pixel_adj = pixel_adj - pre_enc_max_pixel;
+       }
+
+       pixel_adj &= 0xfffffffe;/*clean bit0*/
+
+       WRITE_VPP_REG(ENCL_VIDEO_MAX_LNCNT, pre_enc_max_line + line_adj);
+       WRITE_VPP_REG(ENCL_MAX_LINE_SWITCH_POINT,
+               pre_enc_max_pixel + pixel_adj);
+
+       last_i_vsync = READ_VPP_REG(0x3011);
+
+       if (vlock_log_en && (vlock_log_cnt < vlock_log_size)) {
+               vlock_log[vlock_log_cnt]->enc_line_max = pre_enc_max_line;
+               vlock_log[vlock_log_cnt]->line_num_adj = line_adj;
+               vlock_log[vlock_log_cnt]->enc_pixel_max = pre_enc_max_pixel;
+               vlock_log[vlock_log_cnt]->pixel_num_adj = pixel_adj;
+               vlock_log[vlock_log_cnt]->nT0 = nT0;
+               vlock_log[vlock_log_cnt]->vdif_err = err;
+               vlock_log[vlock_log_cnt]->err_sum = err_accum;
+               vlock_log[vlock_log_cnt]->margin = margin;
+               vlock_reg_get();
+               vlock_log_cnt++;
+       }
+}
+
+static void vlock_enable_step3_pll(void)
+{
+       unsigned int m_reg_value, tmp_value, abs_val, hiu_reg_addr;
+
+       if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
+               hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
+       else
+               hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
+
+       /*vs_i*/
+       tmp_value = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
+       abs_val = abs(vlock_log_last_ivcnt - tmp_value);
+       if ((abs_val > vlock_log_delta_ivcnt) && (vlock_log_delta_en&(1<<0)))
+               pr_info("%s: abs_ivcnt over 0x%x:0x%x(last:0x%x,cur:0x%x)\n",
+                       __func__, vlock_log_delta_ivcnt,
+                       abs_val, vlock_log_last_ivcnt, tmp_value);
+       vlock_log_last_ivcnt = tmp_value;
+       /*vs_o*/
+       tmp_value = READ_VPP_REG(VPU_VLOCK_RO_VS_O_DIST);
+       abs_val = abs(vlock_log_last_ovcnt - tmp_value);
+       if ((abs_val > vlock_log_delta_ovcnt) && (vlock_log_delta_en&(1<<1)))
+               pr_info("%s: abs_ovcnt over 0x%x:0x%x(last:0x%x,cur:0x%x)\n",
+                       __func__, vlock_log_delta_ovcnt,
+                       abs_val, vlock_log_last_ivcnt, tmp_value);
+       vlock_log_last_ovcnt = tmp_value;
+       /*delta_vs*/
+       abs_val = abs(vlock_log_last_ovcnt - vlock_log_last_ivcnt);
+       if ((abs_val > vlock_log_delta_vcnt) && (vlock_log_delta_en&(1<<2)))
+               pr_info("%s: abs_vcnt over 0x%x:0x%x(ivcnt:0x%x,ovcnt:0x%x)\n",
+                       __func__, vlock_log_delta_vcnt,
+                       abs_val, vlock_log_last_ivcnt, vlock_log_last_ovcnt);
+
+       m_reg_value = READ_VPP_REG(VPU_VLOCK_RO_M_INT_FRAC);
+       if (vlock_log_en && (vlock_log_cnt < vlock_log_size)) {
+               vlock_log[vlock_log_cnt]->pll_frac = (m_reg_value & 0xfff) >> 2;
+               vlock_log[vlock_log_cnt]->pll_m = (m_reg_value >> 16) & 0x1ff;
+               vlock_reg_get();
+               vlock_log_cnt++;
+       }
+       if (m_reg_value == 0) {
+               vlock_state = VLOCK_STATE_ENABLE_FORCE_RESET;
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("%s:vlock work abnormal! force reset vlock\n",
+                               __func__);
+               return;
+       }
+       /*vlsi suggest config:don't enable load signal,
+        *on gxtvbb this load signal will effect SSG,
+        *which may result in flashes black
+        */
+       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
+       if (is_meson_gxtvbb_cpu() && (((tmp_value >> 21) & 0x3) != 2))
+               amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 2, 21, 2);
+       /*frac*/
+       amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
+       abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff));
+       if ((abs_val >= vlock_log_delta_frac) && (vlock_log_delta_en&(1<<3)))
+               pr_info("vlock frac delta:%d(0x%x,0x%x)\n",
+                       abs_val, ((m_reg_value & 0xfff) >> 2),
+                       (tmp_value & 0xfff));
+       if (abs_val >= vlock_delta_limit) {
+               tmp_value = (tmp_value & 0xfffff000) |
+                       ((m_reg_value & 0xfff) >> 2);
+               amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
+       }
+       /*m*/
+       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
+       abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (tmp_value & 0x1ff));
+       if ((abs_val > vlock_log_delta_m) && (vlock_log_delta_en&(1<<4)))
+               pr_info("vlock m delta:%d(0x%x,0x%x)\n",
+                       abs_val, ((m_reg_value >> 16) & 0x1ff),
+                       (tmp_value & 0x1ff));
+       if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) {
+               tmp_value = (tmp_value & 0xfffffe00) |
+                       ((m_reg_value >> 16) & 0x1ff);
+               amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
+       }
+}
+/* won't change this function internal seqence,
+ * if really need change,please be carefull
+ */
+void amve_vlock_process(struct vframe_s *vf)
+{
+       struct vinfo_s *vinfo;
+       unsigned int input_hz, output_hz, input_vs_cnt;
+
+       if (vecm_latch_flag & FLAG_VLOCK_DIS) {
+               vlock_disable_step1();
+               vlock_en = 0;
+               vecm_latch_flag &= ~FLAG_VLOCK_DIS;
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("[%s]disable vlock module!!!\n", __func__);
+               return;
+       }
+       vinfo = get_current_vinfo();
+       input_hz = vlock_check_input_hz(vf);
+       output_hz = vlock_check_output_hz(vinfo->sync_duration_num);
+       vlock_dis_cnt_no_vf = 0;
+       if (vecm_latch_flag & FLAG_VLOCK_EN) {
+               vlock_enable_step1(vf, vinfo, input_hz, output_hz);
+               vlock_en = 1;
+               vecm_latch_flag &= ~FLAG_VLOCK_EN;
+       }
+       if (vlock_state == VLOCK_STATE_DISABLE_STEP1_DONE) {
+               vlock_disable_step2();
+               return;
+       }
+       if (vlock_en == 1) {
+               /*@20170728 new add work aound method:
+                **disable vlock for interlace input && hdmitx output
+                */
+               if (((input_hz != output_hz) && (vlock_adapt == 0)) ||
+                       (input_hz == 0) || (output_hz == 0) ||
+                       (((vf->type_original & VIDTYPE_TYPEMASK)
+                               != VIDTYPE_PROGRESSIVE) &&
+                               is_meson_txlx_package_962E())) {
+                       if ((vlock_state != VLOCK_STATE_DISABLE_STEP2_DONE) &&
+                               (vlock_state != VLOCK_STATE_NULL))
+                               vlock_disable_step1();
+                       if (vlock_debug & VLOCK_DEBUG_INFO)
+                               pr_info("[%s]auto disable vlock module for no support case!!!\n",
+                                       __func__);
+                       return;
+               }
+               vlock_vmode_check();
+               if ((vinfo->mode != pre_vmode) ||
+                       (vf->source_type != pre_source_type) ||
+                       (vf->source_mode != pre_source_mode) ||
+                       (input_hz != pre_input_freq) ||
+                       (output_hz != pre_output_freq) ||
+                       vlock_vmode_changed ||
+                       (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET))
+                       vlock_enable_step1(vf, vinfo, input_hz, output_hz);
+               if ((vlock_sync_limit_flag < 10) &&
+                       (vlock_state >= VLOCK_STATE_ENABLE_STEP1_DONE)) {
+                       vlock_sync_limit_flag++;
+                       if ((vlock_sync_limit_flag <= 3) &&
+                               (vlock_mode == VLOCK_MODE_MANUAL_ENC)) {
+                               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+                               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+                               WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0);
+                               WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0);
+                       }
+                       if ((vlock_sync_limit_flag == 4) &&
+                               (vlock_mode == VLOCK_MODE_MANUAL_ENC)) {
+                               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
+                               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
+                       }
+               }
+               if ((vlock_sync_limit_flag == 5) &&
+                       (vlock_state == VLOCK_STATE_ENABLE_STEP1_DONE)) {
+                       /*input_vs_cnt =*/
+                       /*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/
+                       /*      0, 28);*/
+                       input_vs_cnt = XTAL_VLOCK_CLOCK/input_hz;
+                       if (vf->type_original & VIDTYPE_TYPEMASK)
+                               input_vs_cnt = input_vs_cnt << 1;
+                       WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MAX,
+                                       input_vs_cnt*125/100);
+                       WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MIN,
+                                       input_vs_cnt*70/100);
+                       /*cal accum1 value*/
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
+                       /*cal accum0 value*/
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
+                       vlock_state = VLOCK_STATE_ENABLE_STEP2_DONE;
+               } else if (vlock_dynamic_adjust &&
+                       (vlock_sync_limit_flag > 5) &&
+                       (vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) &&
+                       (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) &&
+                       ((vlock_mode == VLOCK_MODE_MANUAL_PLL) ||
+                       (vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
+                       (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC))) {
+                       if (vlock_mode == VLOCK_MODE_MANUAL_ENC)
+                               vlock_enable_step3_enc();
+                       else if (vlock_mode == VLOCK_MODE_MANUAL_PLL)
+                               vlock_enable_step3_pll();
+                       else if (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)
+                               vlock_enable_step3_soft_enc();
+               }
+               if (((vlock_mode == VLOCK_MODE_AUTO_PLL) ||
+                       (vlock_mode == VLOCK_MODE_AUTO_ENC)) &&
+                       vlock_log_en && (vlock_log_cnt < vlock_log_size) &&
+                       (vlock_debug & VLOCK_DEBUG_AUTO_MODE_LOG_EN)) {
+                       vlock_reg_get();
+                       vlock_log_cnt++;
+               }
+       }
+}
+
+void amve_vlock_resume(void)
+{
+       if ((vlock_en == 0) || (vlock_state ==
+               VLOCK_STATE_DISABLE_STEP2_DONE) ||
+               (vlock_state == VLOCK_STATE_NULL))
+               return;
+       if (vlock_state == VLOCK_STATE_DISABLE_STEP1_DONE) {
+               vlock_disable_step2();
+               return;
+       }
+       vlock_dis_cnt_no_vf++;
+       if ((vlock_state != VLOCK_STATE_DISABLE_STEP2_DONE) &&
+               (vlock_dis_cnt_no_vf > vlock_dis_cnt_no_vf_limit)) {
+               vlock_disable_step1();
+               vlock_dis_cnt_no_vf = 0;
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("[%s]auto disable vlock module for no vframe & run disable step1.!!!\n",
+                               __func__);
+       }
+       if (vlock_debug & VLOCK_DEBUG_INFO)
+               pr_info("[%s]auto disable vlock module for no vframe!!!\n",
+                       __func__);
+       if (vlock_dynamic_adjust &&
+               (vlock_sync_limit_flag > 5) &&
+               (vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) &&
+               (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) &&
+               ((vlock_mode == VLOCK_MODE_MANUAL_PLL) ||
+               (vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
+               (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC))) {
+               if (vlock_mode == VLOCK_MODE_MANUAL_ENC)
+                       vlock_enable_step3_enc();
+               else if (vlock_mode == VLOCK_MODE_MANUAL_PLL)
+                       vlock_enable_step3_pll();
+               else if (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)
+                       vlock_enable_step3_soft_enc();
+       }
+}
+void vlock_param_set(unsigned int val, enum vlock_param_e sel)
+{
+       switch (sel) {
+       case VLOCK_EN:
+               vlock_en = val;
+               break;
+       case VLOCK_ADAPT:
+               vlock_adapt = val;
+               break;
+       case VLOCK_MODE:
+               vlock_mode = val;
+               break;
+       case VLOCK_DIS_CNT_LIMIT:
+               vlock_dis_cnt_limit = val;
+               break;
+       case VLOCK_DELTA_LIMIT:
+               vlock_delta_limit = val;
+               break;
+       case VLOCK_DEBUG:
+               vlock_debug = val;
+               break;
+       case VLOCK_DYNAMIC_ADJUST:
+               vlock_dynamic_adjust = val;
+               break;
+       case VLOCK_DIS_CNT_NO_VF_LIMIT:
+               vlock_dis_cnt_no_vf_limit = val;
+               break;
+       case VLOCK_LINE_LIMIT:
+               vlock_line_limit = val;
+               break;
+       default:
+               pr_info("%s:unknown vlock param:%d\n", __func__, sel);
+               break;
+       }
+
+}
+void vlock_status(void)
+{
+       pr_info("\n current vlock parameters status:\n");
+       pr_info("vlock_mode:%d\n", vlock_mode);
+       pr_info("vlock_en:%d\n", vlock_en);
+       pr_info("vlock_adapt:%d\n", vlock_adapt);
+       pr_info("vlock_dis_cnt_limit:%d\n", vlock_dis_cnt_limit);
+       pr_info("vlock_delta_limit:%d\n", vlock_delta_limit);
+       pr_info("vlock_debug:0x%x\n", vlock_debug);
+       pr_info("vlock_dynamic_adjust:%d\n", vlock_dynamic_adjust);
+       pr_info("vlock_state:%d\n", vlock_state);
+       pr_info("vlock_sync_limit_flag:%d\n", vlock_sync_limit_flag);
+       pr_info("pre_vmode:%d\n", pre_vmode);
+       pr_info("pre_hiu_reg_m:0x%x\n", pre_hiu_reg_m);
+       pr_info("pre_hiu_reg_frac:0x%x\n", pre_hiu_reg_frac);
+       pr_info("pre_enc_max_line:0x%x\n", pre_enc_max_line);
+       pr_info("pre_enc_max_pixel:0x%x\n", pre_enc_max_pixel);
+       pr_info("vlock_dis_cnt:%d\n", vlock_dis_cnt);
+       pr_info("pre_vout_mode:%s\n", pre_vout_mode);
+       pr_info("vlock_dis_cnt_no_vf:%d\n", vlock_dis_cnt_no_vf);
+       pr_info("vlock_dis_cnt_no_vf_limit:%d\n", vlock_dis_cnt_no_vf_limit);
+       pr_info("enc_max_line_addr:0x%x\n", enc_max_line_addr);
+       pr_info("enc_max_pixel_addr:0x%x\n", enc_max_pixel_addr);
+       pr_info("enc_video_mode_addr:0x%x\n", enc_video_mode_addr);
+       pr_info("enc_max_line_switch_addr:0x%x\n", enc_max_line_switch_addr);
+       pr_info("vlock_capture_limit:0x%x\n", vlock_capture_limit);
+       pr_info("vlock_line_limit:%d\n", vlock_line_limit);
+}
+void vlock_reg_dump(void)
+{
+       unsigned int addr;
+
+       pr_info("----dump vlock reg----\n");
+       for (addr = (0x3000); addr <= (0x3020); addr++)
+               pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
+                       (0xd0100000+(addr<<2)), addr,
+                       READ_VPP_REG(addr));
+}
+/*work around method for vlock process hdmirx input interlace source.@20170803
+ **for interlace input,TOP and BOT have one line delta,
+ **Which may cause vlock output jitter.
+ **The work around method is that changing vlock input select.
+ **So input vsync cnt may be stable,
+ **However the input hz should be div 2 as vlock input setting
+ */
+void vdin_vlock_input_sel(unsigned int type,
+       enum vframe_source_type_e source_type)
+{
+       type = type & VIDTYPE_TYPEMASK;
+       if ((type == 0) || (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC))
+               return;
+       if (type == VIDTYPE_INTERLACE_TOP) {
+               if ((source_type == VFRAME_SOURCE_TYPE_TUNER) ||
+                       (source_type == VFRAME_SOURCE_TYPE_CVBS))
+                       /* Input Vsync source select from tv-decoder */
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 2, 16, 3);
+               else if (source_type == VFRAME_SOURCE_TYPE_HDMI)
+                       /* Input Vsync source select from hdmi-rx */
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 16, 3);
+       } else
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 7, 16, 3);
+}
+EXPORT_SYMBOL(vdin_vlock_input_sel);
+/*video lock end*/
+
diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.h b/drivers/amlogic/media/enhancement/amvecm/vlock.h
new file mode 100644 (file)
index 0000000..18b7a09
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * drivers/amlogic/media/enhancement/amvecm/vlock.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 __AM_VLOCK_H
+#define __AM_VLOCK_H
+
+#include <linux/amlogic/media/vfm/vframe.h>
+#include "linux/amlogic/media/amvecm/ve.h"
+
+#define VLOCK_REG_NUM  33
+
+struct vlock_log_s {
+       unsigned int pll_m;
+       unsigned int pll_frac;
+       signed int line_num_adj;
+       unsigned int enc_line_max;
+       signed int pixel_num_adj;
+       unsigned int enc_pixel_max;
+       signed int nT0;
+       signed int vdif_err;
+       signed int err_sum;
+       signed int margin;
+       unsigned int vlock_regs[VLOCK_REG_NUM];
+};
+
+enum vlock_param_e {
+       VLOCK_EN = 0x0,
+       VLOCK_ADAPT,
+       VLOCK_MODE,
+       VLOCK_DIS_CNT_LIMIT,
+       VLOCK_DELTA_LIMIT,
+       VLOCK_DEBUG,
+       VLOCK_DYNAMIC_ADJUST,
+       VLOCK_STATE,
+       VLOCK_SYNC_LIMIT_FLAG,
+       VLOCK_DIS_CNT_NO_VF_LIMIT,
+       VLOCK_LINE_LIMIT,
+       VLOCK_PARAM_MAX,
+};
+
+extern void amve_vlock_process(struct vframe_s *vf);
+extern void amve_vlock_resume(void);
+extern void vlock_param_set(unsigned int val, enum vlock_param_e sel);
+extern void vlock_status(void);
+extern void vlock_reg_dump(void);
+extern void vlock_log_start(void);
+extern void vlock_log_stop(void);
+extern void vlock_log_print(void);
+
+
+#define VLOCK_STATE_NULL 0
+#define VLOCK_STATE_ENABLE_STEP1_DONE 1
+#define VLOCK_STATE_ENABLE_STEP2_DONE 2
+#define VLOCK_STATE_DISABLE_STEP1_DONE 3
+#define VLOCK_STATE_DISABLE_STEP2_DONE 4
+#define VLOCK_STATE_ENABLE_FORCE_RESET 5
+
+/* video lock */
+#define VLOCK_MODE_AUTO_ENC 0
+#define VLOCK_MODE_AUTO_PLL 1
+#define VLOCK_MODE_MANUAL_PLL 2
+#define VLOCK_MODE_MANUAL_ENC 3
+#define VLOCK_MODE_MANUAL_SOFT_ENC 4
+
+#define XTAL_VLOCK_CLOCK   24000000/*vlock use xtal clock*/
+
+/*vlock_debug mask*/
+#define VLOCK_DEBUG_INFO (1 << 0)
+#define VLOCK_DEBUG_FLUSH_REG_DIS (1 << 1)
+#define VLOCK_DEBUG_ENC_LINE_ADJ_DIS (1 << 2)
+#define VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS (1 << 3)
+#define VLOCK_DEBUG_AUTO_MODE_LOG_EN (1 << 4)
+
+/* 0:enc;1:pll;2:manual pll */
+extern unsigned int vlock_mode;
+extern unsigned int vlock_en;
+extern unsigned int vecm_latch_flag;
+extern void __iomem *amvecm_hiu_reg_base;
+
+extern void lcd_ss_enable(bool flag);
+extern unsigned int lcd_ss_status(void);
+extern int amvecm_hiu_reg_read(unsigned int reg, unsigned int *val);
+extern int amvecm_hiu_reg_write(unsigned int reg, unsigned int val);
+extern void vdin_vlock_input_sel(unsigned int type,
+       enum vframe_source_type_e source_type);
+#endif
+
index 8110ff4..a7b7a21 100644 (file)
@@ -197,5 +197,8 @@ extern void vdin_source_bitdepth_reinit(struct vdin_dev_s *devp);
 extern void set_invert_top_bot(bool invert_flag);
 extern void vdin_clk_onoff(struct vdin_dev_s *devp, bool onoff);
 extern enum tvin_force_color_range_e color_range_force;
+
+extern void vdin_vlock_input_sel(unsigned int type,
+       enum vframe_source_type_e source_type);
 #endif
 
index 54bf28f..3265b85 100644 (file)
@@ -1262,6 +1262,8 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
 
        last_field_type = devp->curr_field_type;
        devp->curr_field_type = vdin_get_curr_field_type(devp);
+       vdin_vlock_input_sel(devp->curr_field_type,
+               devp->curr_wr_vfe->vf.source_type);
 
        /* ignore the unstable signal */
        state = tvin_get_sm_status(devp->index);