vlock: vlock for tl1 [1/1]
authorYong Qin <yong.qin@amlogic.com>
Wed, 19 Dec 2018 06:56:40 +0000 (14:56 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Wed, 26 Dec 2018 01:53:19 +0000 (17:53 -0800)
PD#SWPL-3129

Problem:
1.verify manual pll mode
2.modify vlock hiu register access api
3.add a new fsm for tl1 test
4.add chip match data

Solution:
add function for tl1

Verify:
verified on tl1

Change-Id: I75f8d2a40437056135f8dd0fb241016a9ea680df
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts
arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts
drivers/amlogic/clk/tl1/tl1.h
drivers/amlogic/media/enhancement/amvecm/amvecm.c
drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h
drivers/amlogic/media/enhancement/amvecm/vlock.c
drivers/amlogic/media/enhancement/amvecm/vlock.h
include/linux/amlogic/media/amvecm/amvecm.h

index 0a20a90..9b6d1a0 100644 (file)
        };
 
        amlvecm {
-               compatible = "amlogic, vecm";
+               compatible = "amlogic, vecm-tl1";
                dev_name = "aml_vecm";
                status = "okay";
                gamma_en = <1>;/*1:enabel ;0:disable*/
index ab460d0..dfdb037 100644 (file)
        };
 
        amlvecm {
-               compatible = "amlogic, vecm";
+               compatible = "amlogic, vecm-tl1";
                dev_name = "aml_vecm";
                status = "okay";
                gamma_en = <1>;/*1:enabel ;0:disable*/
index f8f0377..e678f65 100644 (file)
 #define HHI_SYS_PLL_CNTL5              0x308 /* 0xc2 offset in datasheet */
 #define HHI_SYS_PLL_CNTL6              0x30c /* 0xc3 offset in datasheet */
 
+#if 0/*tl1 no*/
 #define HHI_HDMI_PLL_CNTL              0x320 /* 0xc8 offset in datasheet */
 #define HHI_HDMI_PLL_CNTL2             0x324 /* 0xc9 offset in datasheet */
 #define HHI_HDMI_PLL_CNTL3             0x328 /* 0xca offset in datasheet */
 #define HHI_HDMI_PLL_CNTL4             0x32C /* 0xcb offset in datasheet */
 #define HHI_HDMI_PLL_CNTL5             0x330 /* 0xcc offset in datasheet */
+#endif
 #define HHI_VID_LOCK_CLK_CNTL          0x3c8 /* 0xf2 offset in datasheet1 */
 #define HHI_BT656_CLK_CNTL             0x3d4 /* 0xf5 offset in datasheet1 */
 #define HHI_SPICC_CLK_CNTL             0x3dc /* 0xf7 offset in datasheet1 */
index 8b8103d..5dc2010 100644 (file)
@@ -31,6 +31,8 @@
 #include <linux/stat.h>
 #include <linux/errno.h>
 #include <linux/uaccess.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
 /* #include <linux/amlogic/aml_common.h> */
 #include <linux/ctype.h>/* for parse_para_pq */
 #include <linux/vmalloc.h>
@@ -128,7 +130,7 @@ static struct hdr_metadata_info_s vpp_hdr_metadata_s;
 static int vdj_mode_flg;
 struct am_vdj_mode_s vdj_mode_s;
 
-void __iomem *amvecm_hiu_reg_base;/* = *ioremap(0xc883c000, 0x2000); */
+/*void __iomem *amvecm_hiu_reg_base;*//* = *ioremap(0xc883c000, 0x2000); */
 
 static int debug_amvecm;
 module_param(debug_amvecm, int, 0664);
@@ -721,6 +723,7 @@ static ssize_t amvecm_vlock_store(struct class *cla,
                sel = VLOCK_SUPPORT;
        } else if (!strncmp(parm[0], "enable", 6)) {
                vecm_latch_flag |= FLAG_VLOCK_EN;
+               vlock_set_en(true);
        } else if (!strncmp(parm[0], "disable", 7)) {
                vecm_latch_flag |= FLAG_VLOCK_DIS;
        } else if (!strncmp(parm[0], "status", 6)) {
@@ -5988,11 +5991,40 @@ static const struct file_operations amvecm_fops = {
 #endif
        .poll = amvecm_poll,
 };
+
+static const struct vecm_match_data_s vecm_dt_xxx = {
+       .vlk_support = true,
+       .vlk_new_fsm = 0,
+       .vlk_hwver = vlock_hw_org,
+       .vlk_phlock_en = false,
+};
+
+static const struct vecm_match_data_s vecm_dt_tl1 = {
+       .vlk_support = true,
+       .vlk_new_fsm = 1,
+       .vlk_hwver = vlock_hw_ver2,
+       .vlk_phlock_en = true,
+};
+
+static const struct of_device_id aml_vecm_dt_match[] = {
+       {
+               .compatible = "amlogic, vecm",
+               .data = &vecm_dt_xxx,
+       },
+       {
+               .compatible = "amlogic, vecm-tl1",
+               .data = &vecm_dt_tl1,
+       },
+       {},
+};
+
 static void aml_vecm_dt_parse(struct platform_device *pdev)
 {
        struct device_node *node;
        unsigned int val;
        int ret;
+       const struct of_device_id *of_id;
+       struct vecm_match_data_s *matchdata;
 
        node = pdev->dev.of_node;
        /* get integer value */
@@ -6031,6 +6063,18 @@ static void aml_vecm_dt_parse(struct platform_device *pdev)
                        pr_info("Can't find  tx_op_color_primary.\n");
                else
                        tx_op_color_primary = val;
+
+               /*get compatible matched device, to get chip related data*/
+               of_id = of_match_device(aml_vecm_dt_match, &pdev->dev);
+               if (of_id != NULL) {
+                       pr_info("%s", of_id->compatible);
+                       matchdata = (struct vecm_match_data_s *)of_id->data;
+               } else {
+                       matchdata = (struct vecm_match_data_s *)&vecm_dt_xxx;
+                       pr_info("unable to get matched device\n");
+               }
+               vlock_dt_match_init(matchdata);
+
                /*vlock param config*/
                vlock_param_config(node);
        }
@@ -6158,16 +6202,7 @@ static int aml_vecm_probe(struct platform_device *pdev)
        if (is_meson_g12a_cpu() || is_meson_g12b_cpu())
                sdr_mode = 2;
 
-       /*config vlock mode*/
-       /*todo:txlx & g9tv support auto pll,*/
-       /*but support not good,need vlsi support optimize*/
-       vlock_mode = VLOCK_MODE_MANUAL_PLL;
-       if (is_meson_gxtvbb_cpu() ||
-               is_meson_txl_cpu() || is_meson_txlx_cpu()
-               || is_meson_txhd_cpu())
-               vlock_en = 1;
-       else
-               vlock_en = 0;
+       vlock_status_init();
        hdr_init(&amvecm_dev.hdr_d);
        aml_vecm_dt_parse(pdev);
 
@@ -6259,13 +6294,6 @@ static void amvecm_shutdown(struct platform_device *pdev)
        lc_free();
 }
 
-static const struct of_device_id aml_vecm_dt_match[] = {
-       {
-               .compatible = "amlogic, vecm",
-       },
-       {},
-};
-
 static struct platform_driver aml_vecm_driver = {
        .driver = {
                .name = "aml_vecm",
@@ -6284,16 +6312,19 @@ static struct platform_driver aml_vecm_driver = {
 
 static int __init aml_vecm_init(void)
 {
-       unsigned int hiu_reg_base;
+       /*unsigned int hiu_reg_base;*/
 
        pr_info("%s:module init\n", __func__);
+       #if 0
        /* remap the hiu bus */
        if (is_meson_txlx_cpu() || is_meson_txhd_cpu() ||
-               is_meson_g12a_cpu() || is_meson_g12b_cpu())
+               is_meson_g12a_cpu() || is_meson_g12b_cpu()
+               || is_meson_tl1_cpu())
                hiu_reg_base = 0xff63c000;
        else
                hiu_reg_base = 0xc883c000;
        amvecm_hiu_reg_base = ioremap(hiu_reg_base, 0x2000);
+       #endif
        if (platform_driver_register(&aml_vecm_driver)) {
                pr_err("failed to register bl driver module\n");
                return -ENODEV;
@@ -6305,7 +6336,7 @@ static int __init aml_vecm_init(void)
 static void __exit aml_vecm_exit(void)
 {
        pr_info("%s:module exit\n", __func__);
-       iounmap(amvecm_hiu_reg_base);
+       /*iounmap(amvecm_hiu_reg_base);*/
        platform_driver_unregister(&aml_vecm_driver);
 }
 
index ec7f639..6810134 100644 (file)
 /*ve dither*/
 #define VPP_VE_DITHER_CTRL             0x3120
 
+/* TL1 */
+/*offset 0x1000*/
+#define HHI_TCON_PLL_CNTL0                         0x20
+#define HHI_TCON_PLL_CNTL1                         0x21
+#define HHI_HDMI_PLL_VLOCK_CNTL                         0xd1
+
 /* for pll bug */
-#define HHI_HDMI_PLL_CNTL                          0x10c8
-#define HHI_HDMI_PLL_CNTL2                         0x10c9
-#define HHI_VID_LOCK_CLK_CNTL                  0x10f2
-#define HHI_HDMI_PLL_CNTL6                         0x10cd
+
+#define HHI_HDMI_PLL_CNTL                          0xc8
+#define HHI_HDMI_PLL_CNTL2                         0xc9
+#define HHI_VID_LOCK_CLK_CNTL                  0xf2
+#define HHI_HDMI_PLL_CNTL6                         0xcd
+
 /* for vlock enc mode adjust begin */
 #define ENCL_VIDEO_MAX_LNCNT            0x1cbb
 #define ENCL_VIDEO_MAX_PXCNT 0x1cb0
 #define ENCT_MAX_LINE_SWITCH_POINT 0x1c88
 /* for vlock enc mode adjust end */
 
-#define HHI_VID_LOCK_CLK_CNTL                  0x10f2
-
 #define VDIN_MEAS_VS_COUNT_LO 0x125c
+/*for vlock*/
 /*after GXL new add CNTL1,same with CNTL2 on G9TV/GXTVBB*/
-#define HHI_HDMI_PLL_CNTL1                         0x10c9
+#define HHI_HDMI_PLL_CNTL1                         0xc9
 /*after GXL CNTL5[bit3] is same with CNTL6[bit20] on G9TV/GXTVBB*/
-#define HHI_HDMI_PLL_CNTL5                         0x10cd
+#define HHI_HDMI_PLL_CNTL5                         0xcd
 
 
 /* #define VI_HIST_CTRL                             0x2e00 */
index 8ce8c0c..c1d44c0 100644 (file)
@@ -102,6 +102,12 @@ 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;
+static unsigned int hhi_pll_reg_m;
+static unsigned int hhi_pll_reg_frac;
+
+static struct stvlock_sig_sts vlock;
+
+/*static unsigned int hhi_pll_reg_vlock_ctl;*/
 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);
@@ -141,13 +147,17 @@ 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));
+       /**val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2));*/
+       *val = aml_read_hiubus(reg);
+       /*pr_info("vlock rd hiu reg:0x%x,0x%x\n", (reg - 0x1000), *val);*/
        return 0;
 }
 
 int amvecm_hiu_reg_write(unsigned int reg, unsigned int val)
 {
-       writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2)));
+       /*writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2)));*/
+       /*pr_info("vlock rd hiu reg:0x%x,0x%x\n", (reg - 0x1000), val);*/
+       aml_write_hiubus(reg, val);
        return 0;
 }
 static int amvecm_hiu_reg_write_bits(unsigned int reg, unsigned int value,
@@ -224,10 +234,9 @@ 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_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
                        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,
@@ -246,7 +255,35 @@ static void vlock_enable(bool enable)
                else
                        amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5,
                                enable, 3, 1);
+       } else if (is_meson_tl1_cpu()) {
+               /*reset*/
+               if (vlock_mode & VLOCK_MODE_MANUAL_PLL) {
+                       #if 0
+                       if (enable == 1) {
+
+                               if (vlock_debug & VLOCK_DEBUG_INFO)
+                                       pr_info("tl1 vlock enable\n");
+                               amvecm_hiu_reg_write_bits(hhi_pll_reg_vlock_ctl,
+                                       1, 0, 1);
+                       } else {
+                               if (vlock_debug & VLOCK_DEBUG_INFO)
+                                       pr_info("tl1 vlock disable\n");
+                               amvecm_hiu_reg_write_bits(hhi_pll_reg_vlock_ctl,
+                                       0, 0, 1);
+                       }
+                       #endif
+               } else {
+                       /*reset*/
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
+                       if (!enable)
+                               amvecm_hiu_reg_write_bits(
+                                       HHI_HDMI_PLL_VLOCK_CNTL, 0, 1, 2);
+               }
        }
+
+       if (vlock_debug & VLOCK_DEBUG_INFO)
+               pr_info(">>>[%s] (%d)\n", __func__, enable);
 }
 static void vlock_hw_reinit(struct vlock_regs_s *vlock_regs, unsigned int len)
 {
@@ -256,14 +293,22 @@ static void vlock_hw_reinit(struct vlock_regs_s *vlock_regs, unsigned int len)
                return;
        for (i = 0; i < len; i++)
                WRITE_VPP_REG(vlock_regs[i].addr, vlock_regs[i].val);
+
+       if (vlock_debug & VLOCK_DEBUG_INFO)
+               pr_info("[%s]\n", __func__);
 }
 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 freq_hz = 0;
        unsigned int reg_value = 0, hiu_reg_value, hiu_reg_value_2;
-       unsigned int hiu_m_val, hiu_frac_val, temp_value;
+       unsigned int hiu_m_val = 0, hiu_frac_val = 0, temp_value;
 
+       if (vlock_debug & VLOCK_DEBUG_INFO) {
+               pr_info(">>>[%s]\n", __func__);
+               pr_info("inputHz:%d,outputHz:%d\n", input_hz, output_hz);
+               pr_info("type_original:0x%x\n", vf->type_original);
+       }
        amvecm_hiu_reg_write(HHI_VID_LOCK_CLK_CNTL, 0x80);
        if ((vlock_mode & (VLOCK_MODE_AUTO_ENC |
                VLOCK_MODE_MANUAL_ENC |
@@ -272,6 +317,7 @@ static void vlock_setting(struct vframe_s *vf,
                vlock_hw_reinit(vlock_enc_setting, VLOCK_DEFAULT_REG_SIZE);
                /*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 */
@@ -292,10 +338,12 @@ static void vlock_setting(struct vframe_s *vf,
                }
                /* enable to adjust enc */
                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 (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) {
+                       /*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
@@ -303,8 +351,14 @@ static void vlock_setting(struct vframe_s *vf,
                 *bit8~15:output freq
                 */
                if ((vf->type_original & VIDTYPE_TYPEMASK) &&
-                       !(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC))
-                       input_hz = input_hz >> 1;
+                       !(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC)) {
+                       /*tl1 fix i problem*/
+                       if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1)
+                               input_hz = input_hz >> 1;
+                       else
+                               WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
+                                               1, 28, 1);
+               }
                freq_hz = input_hz | (output_hz << 8);
                WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16);
                /*
@@ -333,8 +387,17 @@ static void vlock_setting(struct vframe_s *vf,
                 *bit0~7:input freq
                 *bit8~15:output freq
                 */
-               if (vf->type_original & VIDTYPE_TYPEMASK)
-                       input_hz = input_hz >> 1;
+               if (vf->type_original & VIDTYPE_TYPEMASK) {
+                       if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1)
+                               input_hz = input_hz >> 1;
+                       else
+                               WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
+                                               1, 28, 1);
+               } else {
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1))
+                               WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL,
+                                               0, 28, 1);
+               }
                freq_hz = input_hz | (output_hz << 8);
                WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16);
                /*
@@ -349,10 +412,15 @@ static void vlock_setting(struct vframe_s *vf,
                /*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,
+               amvecm_hiu_reg_read(hhi_pll_reg_m, &hiu_reg_value);
+               amvecm_hiu_reg_read(hhi_pll_reg_frac,
                        &hiu_reg_value_2);
-               if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) {
+               if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) {
+                       hiu_m_val = hiu_reg_value & 0xff;
+                       /*discard low 5 bits*/
+                       hiu_frac_val = (hiu_reg_value_2 >> 5) & 0xfff;
+                       reg_value = (hiu_m_val << 12) + hiu_frac_val;
+               } else 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) {
@@ -366,6 +434,12 @@ static void vlock_setting(struct vframe_s *vf,
                        }
                        reg_value = (hiu_m_val << 12)
                                + (hiu_frac_val << 2);
+               } else {
+                       pr_info("err: m f value\n");
+               }
+               if (vlock_debug & VLOCK_DEBUG_INFO) {
+                       pr_info("hiu_m_val=0x%x\n", hiu_m_val);
+                       pr_info("hiu_frac_val=0x%x\n", hiu_frac_val);
                }
                WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, reg_value, 0, 21);
                /*vlock_pll_adj_limit = (reg_value * 0x8000) >> 24;*/
@@ -404,29 +478,33 @@ static void vlock_setting(struct vframe_s *vf,
        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);
+
+       /*enable vlock*/
        WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 31, 1);
 }
 void vlock_vmode_check(void)
 {
        const struct vinfo_s *vinfo;
-       unsigned int t0, t1, hiu_reg_addr;
+       unsigned int t0, t1;
 
        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;
        if ((vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE) ||
                (pre_hiu_reg_m == 0)) {
                if (vlock_mode & (VLOCK_MODE_MANUAL_PLL |
                        VLOCK_MODE_AUTO_PLL)) {
-                       amvecm_hiu_reg_read(hiu_reg_addr, &t0);
-                       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &t1);
-                       pre_hiu_reg_frac = t0 & 0xfff;
-                       pre_hiu_reg_m = t1 & 0x1ff;
+                       amvecm_hiu_reg_read(hhi_pll_reg_frac, &t0);
+                       amvecm_hiu_reg_read(hhi_pll_reg_m, &t1);
+                       if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) {
+                               pre_hiu_reg_frac = (t0 >> 5) & 0xfff;
+                               pre_hiu_reg_m = t1 & 0xff;
+                       } else {
+                               pre_hiu_reg_frac = t0 & 0xfff;
+                               pre_hiu_reg_m = t1 & 0x1ff;
+                       }
                }
                if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
                        VLOCK_MODE_AUTO_ENC |
@@ -479,7 +557,6 @@ void vlock_vmode_check(void)
 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);
@@ -487,24 +564,41 @@ static void vlock_disable_step1(void)
        if ((vlock_mode & (VLOCK_MODE_MANUAL_PLL |
                VLOCK_MODE_AUTO_PLL |
                VLOCK_MODE_MANUAL_SOFT_ENC))) {
-               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) {
-                       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 (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) {
+                       amvecm_hiu_reg_read(hhi_pll_reg_frac,
+                               &tmp_value);
+                       m_reg_value = (tmp_value >> 5) & 0xfff;
+                       if (m_reg_value != pre_hiu_reg_frac) {
+                               tmp_value = (tmp_value & 0xfffff000) |
+                                       (pre_hiu_reg_frac & 0xfff);
+                               amvecm_hiu_reg_write(hhi_pll_reg_frac,
+                                       tmp_value);
+                       }
+                       amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);
+                       m_reg_value = tmp_value & 0xff;
+                       if ((m_reg_value != pre_hiu_reg_m) &&
+                               (pre_hiu_reg_m != 0)) {
+                               tmp_value = (tmp_value & 0xffffff00) |
+                                       (pre_hiu_reg_m & 0xff);
+                               amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value);
+                       }
+               } else {
+                       amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);
+                       m_reg_value = tmp_value & 0xfff;
+                       if (m_reg_value != pre_hiu_reg_frac) {
+                               tmp_value = (tmp_value & 0xfffff000) |
+                                       (pre_hiu_reg_frac & 0xfff);
+                               amvecm_hiu_reg_write(hhi_pll_reg_frac,
+                                       tmp_value);
+                       }
+                       amvecm_hiu_reg_read(hhi_pll_reg_m, &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_pll_reg_m, tmp_value);
+                       }
                }
        }
        if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
@@ -537,11 +631,14 @@ static void vlock_disable_step1(void)
        }
        vlock_pll_stable_cnt = 0;
        vlock_enc_stable_flag = 0;
+       if (vlock_debug & VLOCK_DEBUG_INFO)
+               pr_info(">>>[%s]\n", __func__);
 }
 
 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--;
@@ -556,10 +653,16 @@ static void vlock_disable_step2(void)
                /* 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);
+               if (is_meson_gxtvbb_cpu()) {
+                       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val);
+                       if (((temp_val >> 21) & 0x3) != 0)
+                               amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6,
+                                       0, 21, 2);
+               }
        }
+
+       if (vlock_debug & VLOCK_DEBUG_INFO)
+               pr_info(">>>[%s]\n", __func__);
 }
 static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo,
        unsigned int input_hz, unsigned int output_hz)
@@ -584,10 +687,13 @@ static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo,
        vlock_sync_limit_flag = 0;
        vlock_vmode_changed = 0;
        vlock_dis_cnt = 0;
-       vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
+       /*vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;*/
        vlock_pll_stable_cnt = 0;
        vlock_log_cnt = 0;
        vlock_enc_stable_flag = 0;
+
+       if (vlock_debug & VLOCK_DEBUG_INFO)
+               pr_info(">>>[%s]\n", __func__);
 }
 
 void vlock_log_start(void)
@@ -715,6 +821,8 @@ static void vlock_enable_step3_enc(void)
                vlock_reg_get();
                vlock_log_cnt++;
        }
+       if (vlock_debug & VLOCK_DEBUG_INFO)
+               pr_info(">>>[%s]\n", __func__);
 }
 
 static void vlock_enable_step3_soft_enc(void)
@@ -840,7 +948,10 @@ static void vlock_enable_step3_soft_enc(void)
                vlock_reg_get();
                vlock_log_cnt++;
        }
+       if (vlock_debug & VLOCK_DEBUG_INFO)
+               pr_info(">>>[%s]\n", __func__);
 }
+
 /*check pll adj value (0x3020),otherwise may cause blink*/
 static void vlock_pll_adj_limit_check(unsigned int *pll_val)
 {
@@ -863,16 +974,12 @@ static void vlock_pll_adj_limit_check(unsigned int *pll_val)
                }
        }
 }
+
 static void vlock_enable_step3_pll(void)
 {
-       unsigned int m_reg_value, tmp_value, abs_val, hiu_reg_addr;
+       unsigned int m_reg_value, tmp_value, abs_val;
        unsigned int ia, oa, abs_cnt;
 
-       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);
@@ -913,18 +1020,26 @@ static void vlock_enable_step3_pll(void)
                return;
        }
        /*check adjust delta limit*/
-       vlock_pll_adj_limit_check(&m_reg_value);
+       if (vlock.dtdata->vlk_hwver < vlock_hw_ver2)
+               vlock_pll_adj_limit_check(&m_reg_value);
 
        /*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);
-       /*add delta count check*/
-       /*for interlace input need div 2*/
-       if (vlock_intput_type)
+       if (is_meson_gxtvbb_cpu()) {
+               amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
+               if (((tmp_value >> 21) & 0x3) != 2)
+                       amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 2, 21, 2);
+       }
+
+       /* add delta count check
+        *for interlace input need div 2
+        *0:progressive type
+        *1:interlace type
+        */
+       if (vlock_intput_type &&
+               (vlock.dtdata->vlk_hwver < vlock_hw_ver2))
                ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST) / 2;
        else
                ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
@@ -936,45 +1051,69 @@ static void vlock_enable_step3_pll(void)
                return;
        }
        /*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),
+       amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value);
+       if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) {
+               abs_val = abs(((m_reg_value & 0xfff) >> 2) -
                        (tmp_value & 0xfff));
-       if ((abs_val >= vlock_delta_limit) &&
-               (abs_cnt > vlock_delta_cnt_limit)) {
-               tmp_value = (tmp_value & 0xfffff000) |
-                       ((m_reg_value & 0xfff) >> 2);
-               amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
-               vlock_pll_val_last &= 0xffff0000;
-               vlock_pll_val_last |= (m_reg_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) &&
+                       (abs_cnt > vlock_delta_cnt_limit)) {
+                       tmp_value = (tmp_value & 0xfffff000) |
+                               ((m_reg_value & 0xfff) >> 2);
+                       amvecm_hiu_reg_write(hhi_pll_reg_frac, tmp_value);
+                       vlock_pll_val_last &= 0xffff0000;
+                       vlock_pll_val_last |= (m_reg_value & 0xfff);
+               }
+               /*check stable by diff frac*/
+               if ((abs_val < (2 * vlock_delta_limit)) &&
+                       (abs_cnt < vlock_enc_adj_limit))
+                       vlock_pll_stable_cnt++;
+               else
+                       vlock_pll_stable_cnt = 0;
+       } else {
+               tmp_value = (tmp_value & 0xfff80000) |
+                               ((m_reg_value & 0xfff) << 5);
+               amvecm_hiu_reg_write(hhi_pll_reg_frac, tmp_value);
        }
-       /*check stable by diff frac*/
-       if ((abs_val < (2 * vlock_delta_limit)) &&
-               (abs_cnt < vlock_enc_adj_limit))
-               vlock_pll_stable_cnt++;
-       else
-               vlock_pll_stable_cnt = 0;
+
        /*m*/
-       amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
-       abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (pre_hiu_reg_m & 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 ((abs_val <= vlock_pll_m_limit) &&
-               (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) &&
-               (abs_cnt > vlock_delta_cnt_limit)) {
-               tmp_value = (tmp_value & 0xfffffe00) |
-                       ((m_reg_value >> 16) & 0x1ff);
-               amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
-               vlock_pll_val_last &= 0x0000ffff;
-               vlock_pll_val_last |= (m_reg_value & 0xffff0000);
+       amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value);
+       if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) {
+               abs_val = abs(((m_reg_value >> 16) & 0xff) -
+                       (pre_hiu_reg_m & 0xff));
+               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 ((abs_val <= vlock_pll_m_limit) &&
+                       (((m_reg_value >> 16) & 0x1ff) !=
+                               (tmp_value & 0x1ff)) &&
+                       (abs_cnt > vlock_delta_cnt_limit)) {
+                       tmp_value = (tmp_value & 0xfffffe00) |
+                               ((m_reg_value >> 16) & 0x1ff);
+                       amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value);
+                       vlock_pll_val_last &= 0x0000ffff;
+                       vlock_pll_val_last |= (m_reg_value & 0xffff0000);
+               }
+       } else {
+               tmp_value = (tmp_value & 0xffffff00) |
+                       ((m_reg_value >> 16) & 0xff);
+               amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value);
        }
+
        /*check stable by diff m*/
-       if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff))
-               vlock_pll_stable_cnt = 0;
+       if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+               if (((m_reg_value >> 16) & 0xff) != (tmp_value & 0xff))
+                       vlock_pll_stable_cnt = 0;
+       } else {
+               if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff))
+                       vlock_pll_stable_cnt = 0;
+       }
 }
 /* won't change this function internal seqence,
  * if really need change,please be carefull and check with vlsi
@@ -998,6 +1137,7 @@ void amve_vlock_process(struct vframe_s *vf)
        vlock_dis_cnt_no_vf = 0;
        if (vecm_latch_flag & FLAG_VLOCK_EN) {
                vlock_enable_step1(vf, vinfo, input_hz, output_hz);
+               vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
                vlock_en = 1;
                vecm_latch_flag &= ~FLAG_VLOCK_EN;
        }
@@ -1035,43 +1175,66 @@ void amve_vlock_process(struct vframe_s *vf)
                        (input_hz != pre_input_freq) ||
                        (output_hz != pre_output_freq) ||
                        vlock_vmode_changed ||
-                       (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET))
+                       (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET)) {
                        vlock_enable_step1(vf, vinfo, input_hz, output_hz);
+                       vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
+               }
                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 |
                                VLOCK_MODE_MANUAL_PLL)))) {
+                               /*reset*/
                                WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
                                WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+                               /*clear first 3 frame internal cnt*/
                                WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0);
                                WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0);
+                               if (vlock_debug & VLOCK_DEBUG_INFO)
+                                       pr_info("amve_vlock_process-0\n");
                        }
                        if ((vlock_sync_limit_flag == 4) &&
                                ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
                                VLOCK_MODE_MANUAL_PLL)))) {
+                               /*release reset*/
                                WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
                                WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
+                               if (vlock_debug & VLOCK_DEBUG_INFO)
+                                       pr_info("amve_vlock_process-1\n");
                        }
                }
+
                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)
+                       /*tl1 not need */
+                       if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1) &&
+                               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);
+                       //WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
                        vlock_state = VLOCK_STATE_ENABLE_STEP2_DONE;
+
+                       /*tl1 auto pll,swich clk need after several frames*/
+                       if (is_meson_tl1_cpu() &&
+                               (vlock_mode & VLOCK_MODE_AUTO_PLL))
+                               amvecm_hiu_reg_write_bits(
+                                       HHI_HDMI_PLL_VLOCK_CNTL, 0x3, 1, 2);
+
+                       if (vlock_debug & VLOCK_DEBUG_INFO)
+                               pr_info("amve_vlock_process-2\n");
                } else if (vlock_dynamic_adjust &&
                        (vlock_sync_limit_flag > 5) &&
                        (vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) &&
@@ -1149,18 +1312,370 @@ void amve_vlock_resume(void)
        }
 }
 
+void vlock_clear_frame_counter(void)
+{
+       vlock.frame_cnt_in = 0;
+       vlock.frame_cnt_no = 0;
+}
+
+void vlock_set_en(bool en)
+{
+       /*if (vlock.dtdata->vlk_support)*/
+               vlock_en = en;
+}
+
+void vlock_status_init(void)
+{
+       /*config vlock mode*/
+       /*todo:txlx & g9tv support auto pll,*/
+       /*but support not good,need vlsi support optimize*/
+       vlock_mode = VLOCK_MODE_MANUAL_PLL;
+       if (is_meson_gxtvbb_cpu() ||
+               is_meson_txl_cpu() || is_meson_txlx_cpu()
+               || is_meson_tl1_cpu())
+               vlock_en = 1;
+       else
+               vlock_en = 0;
+
+       if (is_meson_tl1_cpu()) {
+               hhi_pll_reg_m = HHI_TCON_PLL_CNTL0;
+               hhi_pll_reg_frac = HHI_TCON_PLL_CNTL1;
+               /*hhi_pll_reg_vlock_ctl = HHI_HDMI_PLL_VLOCK_CNTL;*/
+       } else if (get_cpu_type() >=
+               MESON_CPU_MAJOR_ID_GXL) {
+               hhi_pll_reg_m = HHI_HDMI_PLL_CNTL;
+               hhi_pll_reg_frac = HHI_HDMI_PLL_CNTL2;
+       } else {
+               hhi_pll_reg_m = HHI_HDMI_PLL_CNTL;
+               hhi_pll_reg_frac = HHI_HDMI_PLL_CNTL2;
+       }
+
+       vlock.fsm_sts = VLOCK_STATE_NULL;
+       vlock.fsm_prests = VLOCK_STATE_NULL;
+       vlock.vf_sts = false;
+       vlock.vmd_chg = false;
+       vlock.md_support = false;
+       vlock_clear_frame_counter();
+       pr_info("%s vlock_en:%d\n", __func__, vlock_en);
+}
+
+void vlock_dt_match_init(struct vecm_match_data_s *pdata)
+{
+       vlock.dtdata = pdata;
+       /*vlock_en = vlock.dtdata.vlk_support;*/
+       pr_info("vlock dt support: %d\n", vlock.dtdata->vlk_support);
+       pr_info("vlock dt new_fsm: %d\n", vlock.dtdata->vlk_new_fsm);
+       pr_info("vlock dt hwver: %d\n", vlock.dtdata->vlk_hwver);
+       pr_info("vlock dt phlock_en: %d\n", vlock.dtdata->vlk_phlock_en);
+}
+
+#if 1
+
+u32 vlock_fsm_check_support(struct stvlock_sig_sts *pvlock,
+               struct vframe_s *vf)
+{
+       u32 ret = true;
+
+       if (((pvlock->input_hz != pvlock->output_hz) && (vlock_adapt == 0)) ||
+               (pvlock->input_hz == 0) || (pvlock->output_hz == 0) ||
+               (((vf->type_original & VIDTYPE_TYPEMASK)
+                       != VIDTYPE_PROGRESSIVE) &&
+                       is_meson_txlx_package_962E())) {
+
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("[%s] for no support case!!!\n",
+                               __func__);
+               ret = false;
+       }
+
+       if (vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE_PRE) {
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("[%s] for vmode change pre case!!!\n",
+                               __func__);
+               ret = false;
+       }
+
+       return ret;
+}
+
+u32 vlock_fsm_input_check(struct stvlock_sig_sts *vlock, struct vframe_s *vf)
+{
+       u32 ret = 0;
+       u32 vframe_sts;
+       struct vinfo_s *vinfo = NULL;
+
+       if (vf == NULL)
+               vframe_sts = false;
+       else
+               vframe_sts = true;
+
+       if (vf != NULL) {
+               vinfo = get_current_vinfo();
+               vlock->input_hz = vlock_check_input_hz(vf);
+               vlock->output_hz = vlock_check_output_hz(
+                       vinfo->sync_duration_num);
+       }
+
+       /*check vf exist status*/
+       if (vlock->vf_sts != vframe_sts) {
+               vlock->vf_sts = vframe_sts;
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("vlock vfsts chg %d\n", vframe_sts);
+               ret = 1;
+       } else if (vlock_vmode_change_status) {
+               /*check video mode status*/
+               vlock->vmd_chg = true;
+               ret = 1;
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("vlock vmode chg\n");
+       }
+
+       if (vlock->vf_sts)
+               vlock->md_support = vlock_fsm_check_support(vlock, vf);
+
+       return ret;
+}
+
+u32 vlock_fsm_to_en_func(struct stvlock_sig_sts *pvlock,
+               struct vframe_s *vf)
+{
+       u32 ret = 0;
+       struct vinfo_s *vinfo;
+
+       if ((vf->source_type != pre_source_type) ||
+               (vf->source_mode != pre_source_mode) ||
+               (pvlock->input_hz != pre_input_freq) ||
+               (pvlock->output_hz != pre_output_freq) ||
+               vlock_vmode_changed ||
+               (pvlock->fsm_sts ==
+               VLOCK_STATE_ENABLE_FORCE_RESET)) {
+               vinfo = get_current_vinfo();
+               vlock_enable_step1(vf, vinfo,
+               pvlock->input_hz, pvlock->output_hz);
+               ret = 1;
+       }
+
+       return ret;
+}
+
+u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock,
+               struct vframe_s *vf)
+{
+       u32 ret = 0;
+       u32 input_vs_cnt;
+
+       if ((pvlock->frame_cnt_in <= 3) &&
+               ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+               VLOCK_MODE_MANUAL_PLL)))) {
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
+               /*clear first 3 frame internal cnt*/
+               WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0);
+               WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0);
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("%s -0\n", __func__);
+       } else if ((pvlock->frame_cnt_in == 4) &&
+               ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+               VLOCK_MODE_MANUAL_PLL)))) {
+               /*cal accum0 value*/
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
+               /*cal accum1 value*/
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("%s -1\n", __func__);
+       } else if (pvlock->frame_cnt_in == 5) {
+               /*input_vs_cnt =*/
+               /*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/
+               /*      0, 28);*/
+               input_vs_cnt = XTAL_VLOCK_CLOCK/pvlock->input_hz;
+               /*tl1 not need */
+               if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1) &&
+                       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);
+
+               /*
+                * tl1 auto pll,swich clk need after
+                *several frames
+                */
+               if (is_meson_tl1_cpu() &&
+                       IS_AUTO_PLL_MODE(vlock_mode))
+                       amvecm_hiu_reg_write_bits(
+                       HHI_HDMI_PLL_VLOCK_CNTL, 0x3, 1, 2);
+
+               ret = 1;
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("%s -2\n", __func__);
+       }
+
+       return ret;
+}
+
+u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock,
+               struct vframe_s *vf)
+{
+       u32 ret = 0;
+
+       if (vlock_dynamic_adjust &&
+       (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) &&
+       (IS_MANUAL_MODE(vlock_mode))) {
+               if (IS_MANUAL_ENC_MODE(vlock_mode))
+                       vlock_enable_step3_enc();
+               else if (IS_MANUAL_PLL_MODE(vlock_mode))
+                       vlock_enable_step3_pll();
+               else if (IS_MANUAL_SOFTENC_MODE(vlock_mode))
+                       vlock_enable_step3_soft_enc();
+               /*check stable*/
+               /*....*/
+       }
+
+       return ret;
+}
+
+
+void vlock_fsm_monitor(struct vframe_s *vf)
+{
+       u32 changed;
+
+       changed = vlock_fsm_input_check(&vlock, vf);
+       vlock_vmode_check();
+       switch (vlock.fsm_sts) {
+       case VLOCK_STATE_NULL:
+               if (vlock.vf_sts) {
+                       /*have frame in*/
+                       if (vlock.frame_cnt_in++ == 3) {
+                               /*vframe input valid*/
+                               if (vlock.md_support) {
+                                       if (vlock_fsm_to_en_func(&vlock, vf)) {
+                                               vlock_clear_frame_counter();
+                                               vlock.fsm_sts =
+                                               VLOCK_STATE_ENABLE_STEP1_DONE;
+                                       } else {
+                                               /*error waitting here*/
+                                               vlock_clear_frame_counter();
+                                       }
+                               }
+                       }
+               } else if (vlock.vmd_chg) {
+                       vlock_clear_frame_counter();
+                       vlock.vmd_chg = false;
+                       vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP2_DONE;
+               } else {
+                       /*disabled and waitting here*/
+                       vlock_clear_frame_counter();
+               }
+               break;
+
+       case VLOCK_STATE_ENABLE_STEP1_DONE:
+               if (vlock.vf_sts) {
+                       vlock.frame_cnt_in++;
+                       if (vlock_fsm_en_step1_func(&vlock, vf))
+                               vlock.fsm_sts = VLOCK_STATE_ENABLE_STEP2_DONE;
+               } else if (vlock.vmd_chg) {
+                       vlock_clear_frame_counter();
+                       vlock.vmd_chg = false;
+                       vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+               } else {
+                       vlock.frame_cnt_in = 0;
+                       if (vlock.frame_cnt_no++ > vlock_dis_cnt_no_vf_limit) {
+                               /*go to disable state*/
+                               vlock_clear_frame_counter();
+                               vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+                       }
+               }
+               break;
+
+       case VLOCK_STATE_ENABLE_STEP2_DONE:
+               if (vlock.vf_sts) {
+                       if (!vlock.md_support) {
+                               /*function not support*/
+                               vlock_clear_frame_counter();
+                               vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+                       } else if (vecm_latch_flag & FLAG_VLOCK_DIS) {
+                               /*disable vlock by vecm cmd*/
+                               vlock_disable_step1();
+                               vlock_disable_step2();
+                               vlock_en = 0;
+                               vecm_latch_flag &= ~FLAG_VLOCK_DIS;
+                               if (vlock_debug & VLOCK_DEBUG_INFO)
+                                       pr_info("[%s] vlock dis\n", __func__);
+                               vlock_clear_frame_counter();
+                               vlock.fsm_sts = VLOCK_STATE_NULL;
+                       } else {
+                               /*normal mode*/
+                               vlock.frame_cnt_no = 0;
+                               vlock_fsm_en_step2_func(&vlock, vf);
+                       }
+               } else if (vlock.vmd_chg) {
+                       vlock_clear_frame_counter();
+                       vlock.vmd_chg = false;
+                       vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+               } else {
+                       /*no frame input*/
+                       if (vlock.frame_cnt_no++ > vlock_dis_cnt_no_vf_limit) {
+                               /*go to disable state*/
+                               vlock_clear_frame_counter();
+                               vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE;
+                       } else {
+                               vlock_fsm_en_step2_func(&vlock, vf);
+                       }
+               }
+               break;
+
+       case VLOCK_STATE_DISABLE_STEP1_DONE:
+               vlock_disable_step1();
+               vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP2_DONE;
+               break;
+
+       case VLOCK_STATE_DISABLE_STEP2_DONE:
+               vlock_disable_step2();
+               vlock.fsm_sts = VLOCK_STATE_NULL;
+               break;
+
+       default:
+               pr_info("err state %d\n", vlock.fsm_sts);
+               break;
+       }
+
+       /*capture log*/
+       if (((vlock_mode & (VLOCK_MODE_AUTO_PLL |
+               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++;
+       }
+
+       if ((vlock_debug & VLOCK_DEBUG_INFO) &&
+                       vlock.fsm_sts != vlock.fsm_prests) {
+               pr_info(">>> %s fsm %d to %d\n", __func__,
+                       vlock.fsm_prests, vlock.fsm_sts);
+               vlock.fsm_prests = vlock.fsm_sts;
+       }
+}
+#endif
+
 /*new packed separeted from amvecm_on_vs,avoid the influencec of repeate call,
  *which may affect vlock process
  */
 void vlock_process(struct vframe_s *vf)
 {
-       if (probe_ok == 0)
+       if (probe_ok == 0 || !vlock_en)
                return;
 
        /* todo:vlock processs only for tv chip */
-       if (is_meson_gxtvbb_cpu() ||
-               is_meson_txl_cpu() || is_meson_txlx_cpu()
-               || is_meson_txhd_cpu()) {
+       if (vlock.dtdata->vlk_new_fsm)
+               vlock_fsm_monitor(vf);
+       else {
                if (vf != NULL)
                        amve_vlock_process(vf);
                else
@@ -1227,6 +1742,7 @@ void vlock_status(void)
        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("vecm_latch_flag:0x%x\n", vecm_latch_flag);
        pr_info("vlock_sync_limit_flag:%d\n", vlock_sync_limit_flag);
        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);
@@ -1248,17 +1764,28 @@ void vlock_status(void)
        pr_info("vlock_intput_type:%d\n", vlock_intput_type);
        pr_info("vlock_pll_adj_limit:%d\n", vlock_pll_adj_limit);
        pr_info("vlock_pll_val_last:%d\n", vlock_pll_val_last);
+       pr_info("vlk_new_fsm:%d\n", vlock.dtdata->vlk_new_fsm);
        pr_info("vlock driver version :  %s\n", VLOCK_VER);
 }
 void vlock_reg_dump(void)
 {
        unsigned int addr;
+       unsigned int val;
 
        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));
+
+       if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) {
+               for (addr = (0x3021); addr <= (0x302a); addr++)
+                       pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n",
+                               (0xd0100000+(addr<<2)), addr,
+                               READ_VPP_REG(addr));
+               amvecm_hiu_reg_read(HHI_HDMI_PLL_VLOCK_CNTL, &val);
+               pr_info("HIU [0x%04x]=0x%08x\n", HHI_HDMI_PLL_VLOCK_CNTL, val);
+       }
 }
 /*work around method for vlock process hdmirx input interlace source.@20170803
  **for interlace input,TOP and BOT have one line delta,
@@ -1270,8 +1797,17 @@ void vlock_reg_dump(void)
 void vdin_vlock_input_sel(unsigned int type,
        enum vframe_source_type_e source_type)
 {
+       if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2)
+               return;
+       /*
+        *1:fromhdmi rx ,
+        *2:from tv-decoder,
+        *3:from dvin,
+        *4:from dvin,
+        *5:from 2nd bt656
+        */
        vlock_intput_type = type & VIDTYPE_TYPEMASK;
-       if ((vlock_intput_type == 0) ||
+       if ((vlock_intput_type == VIDTYPE_PROGRESSIVE) ||
                (vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC))
                return;
        if (vlock_intput_type == VIDTYPE_INTERLACE_TOP) {
@@ -1351,6 +1887,7 @@ void vlock_param_config(struct device_node *node)
                vlock_mode &= ~VLOCK_MODE_MANUAL_MIX_PLL_ENC;
                vlock_mode |= VLOCK_MODE_MANUAL_PLL;
        }
+       pr_info("param_config vlock_en:%d\n", vlock_en);
 }
 
 int vlock_notify_callback(struct notifier_block *block, unsigned long cmd,
index 96784fb..fee85c5 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/amlogic/media/vfm/vframe.h>
 #include "linux/amlogic/media/amvecm/ve.h"
 
-#define VLOCK_VER "Ref.2018/11/07a"
+#define VLOCK_VER "Ref.2018/12/24"
 
 #define VLOCK_REG_NUM  33
 
@@ -59,6 +59,18 @@ enum vlock_param_e {
        VLOCK_PARAM_MAX,
 };
 
+struct stvlock_sig_sts {
+       u32 fsm_sts;
+       u32 fsm_prests;
+       u32 vf_sts;
+       u32 vmd_chg;
+       u32 frame_cnt_in;
+       u32 frame_cnt_no;
+       u32 input_hz;
+       u32 output_hz;
+       bool md_support;
+       struct vecm_match_data_s *dtdata;
+};
 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);
@@ -84,6 +96,29 @@ extern void vlock_log_print(void);
 #define VLOCK_MODE_MANUAL_SOFT_ENC (1 << 4)
 #define VLOCK_MODE_MANUAL_MIX_PLL_ENC (1 << 5)
 
+
+#define IS_MANUAL_MODE(md)     (md & \
+                               (VLOCK_MODE_MANUAL_PLL | \
+                               VLOCK_MODE_MANUAL_ENC | \
+                               VLOCK_MODE_MANUAL_SOFT_ENC))
+
+#define IS_PLL_MODE(md)        (md & \
+                               (VLOCK_MODE_MANUAL_PLL | \
+                               VLOCK_MODE_AUTO_PLL))
+
+#define IS_AUTO_PLL_MODE(md) (md & \
+                                       VLOCK_MODE_AUTO_PLL)
+
+#define IS_MANUAL_ENC_MODE(md) (md & \
+                               VLOCK_MODE_MANUAL_ENC)
+
+#define IS_MANUAL_PLL_MODE(md) (md & \
+                               VLOCK_MODE_MANUAL_PLL)
+
+#define IS_MANUAL_SOFTENC_MODE(md) (md & \
+                               VLOCK_MODE_MANUAL_SOFT_ENC)
+
+
 #define XTAL_VLOCK_CLOCK   24000000/*vlock use xtal clock*/
 
 #define VLOCK_SUPPORT_HDMI (1 << 0)
@@ -106,7 +141,7 @@ extern void vlock_log_print(void);
 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 __iomem *amvecm_hiu_reg_base;*/
 extern unsigned int probe_ok;
 
 extern void lcd_ss_enable(bool flag);
@@ -123,4 +158,7 @@ extern void vlock_lcd_param_work(struct work_struct *p_work);
 extern int vlock_notify_callback(struct notifier_block *block,
        unsigned long cmd, void *para);
 #endif
+extern void vlock_status_init(void);
+extern void vlock_dt_match_init(struct vecm_match_data_s *pdata);
+extern void vlock_set_en(bool en);
 
index ec6cd64..eeeb64d 100644 (file)
@@ -300,6 +300,29 @@ enum ve_pq_timing_e {
        TIMING_MAX,
 };
 
+enum vlock_hw_ver_e {
+       /*gxtvbb*/
+       vlock_hw_org,
+       /*
+        *txl
+        *txlx
+        */
+       vlock_hw_ver1,
+       /* tl1 later
+        * fix bug:i problem
+        * fix bug:affect ss function
+        * add: phase lock
+        */
+       vlock_hw_ver2,
+};
+
+struct vecm_match_data_s {
+       u32 vlk_support;
+       u32 vlk_new_fsm;
+       enum vlock_hw_ver_e vlk_hwver;
+       u32 vlk_phlock_en;
+};
+
 /*overscan:
  *length 0~31bit :number of crop;
  *src_timing: bit31: on: load/save all crop