vlock: for phase lock sometime can't lock [1/1]
authorYong Qin <yong.qin@amlogic.com>
Mon, 20 May 2019 02:02:25 +0000 (10:02 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Wed, 22 May 2019 05:13:50 +0000 (22:13 -0700)
PD#SWPL-6403

Problem:
vlock phase lock time is not accurate as theoretical value

Solution:
1.change the limite
2.increace the frq and phase lock window
3.lone time unlock, need retry

Verify:
tl1

Change-Id: I67e56e59f53848128e65a54c6a8acf750a03b72d
Signed-off-by: Yong Qin <yong.qin@amlogic.com>
drivers/amlogic/media/enhancement/amvecm/amvecm.c
drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h
drivers/amlogic/media/enhancement/amvecm/vlock.c
drivers/amlogic/media/enhancement/amvecm/vlock.h

index f3d2644..c6433d9 100644 (file)
@@ -745,6 +745,19 @@ static ssize_t amvecm_vlock_store(struct class *cla,
                if (kstrtol(parm[1], 10, &val) < 0)
                        return -EINVAL;
                vlock_set_phase_en(val);
+       } else if (!strncmp(parm[0], "afterfrqlock", 12)) {
+               if (kstrtol(parm[1], 10, &val) < 0)
+                       return -EINVAL;
+               vlock_set_phase_en(val);
+               phase_en_after_frqlock = val;
+               pr_info("phase_en_after_frqlock=%d\n",
+                       phase_en_after_frqlock);
+       } else if (!strncmp(parm[0], "ss_en", 5)) {
+               if (kstrtol(parm[1], 10, &val) < 0)
+                       return -EINVAL;
+               vlock_set_phase_en(val);
+               vlock_ss_en = val;
+               pr_info("vlock_ss_en=%d\n", vlock_ss_en);
        } else {
                pr_info("----cmd list -----\n");
                pr_info("vlock_mode val\n");
@@ -766,7 +779,9 @@ static ssize_t amvecm_vlock_store(struct class *cla,
                pr_info("log_stop\n");
                pr_info("log_print\n");
                pr_info("phase persent\n");
-               pr_info("phlock_en val\n");
+               pr_info("phlock_en 0/1\n");
+               pr_info("afterfrqlock 0/1-phase lock after frq lock\n");
+               pr_info("vlock_ss_en 0/1-enable ss after phase lock\n");
        }
        if (sel < VLOCK_PARAM_MAX)
                vlock_param_set(temp_val, sel);
index 960dfe4..166c479 100644 (file)
@@ -55,12 +55,12 @@ static struct vlock_regs_s vlock_pll_setting[VLOCK_DEFAULT_REG_SIZE] = {
        {0x3001,     0x04053c32   },
        {0x3002,     0x06000000   },
        {0x3003,     0x20780780   },
-       {0x3004,     0x00680680   },
+       {0x3004,     0x00604680   },
        {0x3005,     0x00080000   },
        {0x3006,     0x00070000   },
        {0x3007,     0x00000000   },
        {0x3008,     0x00000000   },
-       {0x3009,     0x00100000   },
+       {0x3009,     0x06000000   },
        {0x300a,     0x00600000   },
        {0x300b,     0x00100000   },
        {0x300c,     0x00600000   },
@@ -77,12 +77,12 @@ static struct vlock_regs_s vlock_pll_setting[VLOCK_DEFAULT_REG_SIZE] = {
 static struct vlock_regs_s vlock_pll_phase_setting[VLOCK_PHASE_REG_SIZE] = {
        {0x3004,         0x00604680},
        {0x3009,         0x06000000},
-       {0x300a,         0x00600000},
+       {0x300a,         0x06000000},
        {0x300b,         0x06000000},
-       {0x300c,         0x00600000},
-       {0x3025,         0x00010000},
+       {0x300c,         0x06000000},
+       {0x3025,         0x00013000},
        {0x3027,         0x00022002},
-       {0x3028,         0x00005000},
+       {0x3028,         0x00008000},
        {0x302a,         0x00022002},
 };
 
index 55195e3..915e686 100644 (file)
@@ -106,9 +106,12 @@ 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;
+u32 phase_en_after_frqlock;
+u32 vlock_ss_en = 1;
 
 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");
@@ -540,16 +543,15 @@ static void vlock_setting(struct vframe_s *vf,
 
        /*initial phase lock setting*/
        if (vlock.phlock_en) {
-               vlock_hw_reinit(vlock_pll_phase_setting, VLOCK_PHASE_REG_SIZE);
-               /*disable pll lock*/
-               /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 3, 1);*/
-
-               /*enable pll mode and enc mode phase lock*/
-               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 3, 0, 2);
-
-               /*reset*/
-               /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);*/
-               /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);*/
+               if (!phase_en_after_frqlock) {
+                       vlock_hw_reinit(vlock_pll_phase_setting,
+                               VLOCK_PHASE_REG_SIZE);
+                       /*disable pll lock*/
+                       /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 3, 1);*/
+
+                       /*enable pll mode and enc mode phase lock*/
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 3, 0, 2);
+               }
        }
 
        /* vlock module output goes to which module */
@@ -781,6 +783,9 @@ static bool vlock_disable_step2(void)
                                amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6,
                                        0, 21, 2);
                }
+
+               vlock_reset(1);
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 0, 2);
                ret = true;
 
                if (vlock_debug & VLOCK_DEBUG_INFO)
@@ -1239,23 +1244,6 @@ static void vlock_enable_step3_pll(void)
                                        pr_info("vlock m: pre=0x%x, rp=0x%x, wr=0x%x\n",
                                        pre_m, new_m, m_reg_value);
                        }
-                       #if 0
-                       /*for test*/
-                       pr_info("vlock m: 0x%x (%d)\n", vlock.val_m, aaa);
-                       if (aaa == 0) {
-                               aaa = 1;
-                               vlock_set_panel_pll_m(vlock.val_m + 1);
-                       } else if (aaa == 1) {
-                               aaa = 2;
-                               vlock_set_panel_pll_m(vlock.val_m);
-                       } else if (aaa == 2) {
-                               aaa = 3;
-                               vlock_set_panel_pll_m(vlock.val_m - 1);
-                       } else if (aaa == 3) {
-                               aaa = 0;
-                               vlock_set_panel_pll_m(vlock.val_m);
-                       }
-                       #endif
                }
        }
 
@@ -1285,6 +1273,7 @@ static void vlock_enable_step3_pll(void)
                else
                        vlock_pll_stable_cnt = 0;
        } else {
+               #if 0
                abs_val = abs((tmp_value & 0x1ffff) -
                        ((m_f_reg_value & 0xfff) << 5));
 
@@ -1293,6 +1282,7 @@ static void vlock_enable_step3_pll(void)
                                (((tmp_value & 0x1ffff) +
                                ((m_f_reg_value & 0xfff) << 5)) >> 1));
                else
+               #endif
                        tmp_value = (tmp_value & 0xfffe0000) |
                                                ((m_f_reg_value & 0xfff) << 5);
                if (((tmp_value & 0x1ffff) !=
@@ -1531,6 +1521,8 @@ void vlock_clear_frame_counter(void)
        vlock.frqlock_sts = false;
        vlock.pll_mode_pause = false;
        /*vlock.frqlock_stable_cnt = 0;*/
+       if (phase_en_after_frqlock)
+               vlock.phlock_en = false;
 }
 
 void vlock_set_en(bool en)
@@ -1617,7 +1609,8 @@ void vlock_status_init(void)
        vlock.phlock_sts = false;
        vlock.frqlock_sts = false;
        vlock.pll_mode_pause = false;
-       vlock.phlock_en = vlock.dtdata->vlk_phlock_en;
+       if (!phase_en_after_frqlock)
+               vlock.phlock_en = vlock.dtdata->vlk_phlock_en;
        /* vlock.phlock_percent = phlock_percent; */
        vlock_clear_frame_counter();
 
@@ -1658,9 +1651,14 @@ void vlock_set_phase(u32 percent)
 
 void vlock_set_phase_en(u32 en)
 {
-       if (en)
+       if (en) {
                vlock.phlock_en = true;
-       else
+
+               vlock_hw_reinit(vlock_pll_phase_setting, VLOCK_PHASE_REG_SIZE);
+               WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 3, 0, 2);
+               vlock_reset(1);
+               vlock_reset(0);
+       } else
                vlock.phlock_en = false;
        pr_info("vlock phlock_en=%d\n", en);
 }
@@ -1851,8 +1849,7 @@ u32 vlock_fsm_to_en_func(struct stvlock_sig_sts *pvlock,
                vinfo = get_current_vinfo();
                vlock_enable_step1(vf, vinfo,
                pvlock->input_hz, pvlock->output_hz);
-               if (IS_PLL_MODE(vlock_mode) &&
-                               pvlock->phlock_en) {
+               if (IS_PLL_MODE(vlock_mode)) {
                        vlock_set_panel_ss(false);
                        pvlock->ss_sts = false;
                }
@@ -1929,13 +1926,14 @@ u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock,
        return ret;
 }
 
-void vlock_fsm_check_lock_sts(struct stvlock_sig_sts *pvlock,
+u32 vlock_fsm_check_lock_sts(struct stvlock_sig_sts *pvlock,
                struct vframe_s *vf)
 {
        u32 frqlock_sts = vlock_get_vlock_flag();
        u32 phlock_sts = vlock_get_phlock_flag();
        u32 pherr;
        static u32 rstflag;
+       u32 ret = 1;
 
        /*check frq lock*/
        if (pvlock->frqlock_sts != frqlock_sts) {
@@ -1946,6 +1944,21 @@ void vlock_fsm_check_lock_sts(struct stvlock_sig_sts *pvlock,
                pvlock->frqlock_sts = frqlock_sts;
        }
 
+       /*enable phase lock after frq lock*/
+       if (phase_en_after_frqlock && !vlock.phlock_en &&
+               pvlock->frqlock_sts && (pvlock->frame_cnt_in > 50)) {
+               if (vlock.dtdata->vlk_phlock_en) {
+                       vlock.phlock_en = vlock.dtdata->vlk_phlock_en;
+                       pr_info("enable phase lock\n");
+                       vlock_hw_reinit(vlock_pll_phase_setting,
+                               VLOCK_PHASE_REG_SIZE);
+                       /*WRITE_VPP_REG(VPU_VLOCK_LOOP1_CTRL0, 0x00601680);*/
+                       WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 3, 0, 2);
+                       vlock_reset(1);
+                       vlock_reset(0);
+               }
+       }
+
        /*check phase error*/
        if (IS_PLL_MODE(vlock_mode) &&
                        pvlock->phlock_en) {
@@ -1967,17 +1980,32 @@ void vlock_fsm_check_lock_sts(struct stvlock_sig_sts *pvlock,
        }
 
        /*check phase lock*/
-       if (pvlock->phlock_en &&
-               (pvlock->phlock_sts != phlock_sts)) {
-               if (vlock_debug & VLOCK_DEBUG_INFO)
-                       pr_info("ph lock sts(%d,%d) cnt:%d\n",
-                       pvlock->phlock_sts,
-                       phlock_sts, pvlock->frame_cnt_in);
-               pvlock->phlock_sts = phlock_sts;
-               if (phlock_sts && !pvlock->ss_sts &&
-                       (pvlock->frame_cnt_in > 25)) {
-                       vlock_set_panel_ss(true);
-                       pvlock->ss_sts = true;
+       if (pvlock->phlock_en) {
+               if (pvlock->phlock_sts != phlock_sts) {
+                       pvlock->phlock_cnt = 0;
+                       if (vlock_debug & VLOCK_DEBUG_INFO)
+                               pr_info("ph lock sts(%d,%d) cnt:%d\n",
+                               pvlock->phlock_sts,
+                               phlock_sts, pvlock->frame_cnt_in);
+                       pvlock->phlock_sts = phlock_sts;
+                       #if 0
+                       if (pvlock->phlock_sts && !pvlock->ss_sts &&
+                               (pvlock->frame_cnt_in > 25)) {
+                               if (vlock_ss_en) {
+                                       pvlock->ss_sts = true;
+                                       vlock_set_panel_ss(true);
+                               }
+                       }
+                       #endif
+               } else {
+                       pvlock->phlock_cnt++;
+                       if (pvlock->phlock_sts && !pvlock->ss_sts &&
+                               (pvlock->phlock_cnt > 50)) {
+                               if (vlock_ss_en) {
+                                       pvlock->ss_sts = true;
+                                       vlock_set_panel_ss(true);
+                               }
+                       }
                }
        }
 
@@ -1985,15 +2013,22 @@ void vlock_fsm_check_lock_sts(struct stvlock_sig_sts *pvlock,
        if (IS_PLL_MODE(vlock_mode) &&
                        pvlock->phlock_en) {
                /*error check*/
-               if ((pvlock->frame_cnt_in >= 3500) && (!pvlock->ss_sts)) {
+               if ((pvlock->frame_cnt_in >= 3000) && (!pvlock->ss_sts)) {
                        if (vlock_debug & VLOCK_DEBUG_INFO)
                                pr_info("vlock warning: set back ss on(%d, %d)\n",
                                frqlock_sts, phlock_sts);
                        /*pvlock->pll_mode_pause = true;*/
-                       pvlock->ss_sts = true;
-                       vlock_set_panel_ss(true);
+                       if (vlock_ss_en) {
+                               pvlock->ss_sts = true;
+                               vlock_set_panel_ss(true);
+                               if (vlock_debug & VLOCK_DEBUG_INFO)
+                                       pr_info("vlock phase err, need retry\n");
+                               return 0;
+                       }
                }
        }
+
+       return ret;
 }
 
 u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock,
@@ -2019,7 +2054,7 @@ u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock,
        /*check phase*/
        vlock_phaselock_check(pvlock, vf);
 
-       vlock_fsm_check_lock_sts(pvlock, vf);
+       ret = vlock_fsm_check_lock_sts(pvlock, vf);
 
        return ret;
 }
@@ -2099,7 +2134,11 @@ void vlock_fsm_monitor(struct vframe_s *vf)
                        } else {
                                /*normal mode*/
                                vlock.frame_cnt_no = 0;
-                               vlock_fsm_en_step2_func(&vlock, vf);
+                               if (vlock_fsm_en_step2_func(&vlock, vf) <= 0) {
+                                       vlock.fsm_sts =
+                                               VLOCK_STATE_DISABLE_STEP1_DONE;
+                                       vlock_clear_frame_counter();
+                               }
                        }
                } else if (vlock.vmd_chg) {
                        vlock_clear_frame_counter();
@@ -2432,12 +2471,14 @@ int vlock_notify_callback(struct notifier_block *block, unsigned long cmd,
                if (vlock.dtdata->vlk_new_fsm &&
                        (vlock.fsm_sts >= VLOCK_STATE_ENABLE_STEP1_DONE) &&
                        (vlock.fsm_sts <= VLOCK_STATE_DISABLE_STEP1_DONE)) {
+                       vlock_set_panel_ss(false);
                        /*stop vlock*/
                        vlock_disable_step1();
                        while (!vlock_disable_step2()) {
                                if (cnt++ > 10)
                                        break;
                        }
+                       vlock_set_panel_ss(true);
                }
                pr_info("vlock: event MODE_CHANGE_PRE %d\n", cnt);
                break;
index 0c8846b..88c3e04 100644 (file)
@@ -23,7 +23,7 @@
 #include <linux/amlogic/media/vfm/vframe.h>
 #include "linux/amlogic/media/amvecm/ve.h"
 
-#define VLOCK_VER "Ref.2019/5/16:finetune phase lock"
+#define VLOCK_VER "Ref.2019/5/20"
 
 #define VLOCK_REG_NUM  33
 
@@ -73,6 +73,7 @@ struct stvlock_sig_sts {
        u32 phlock_percent;
        u32 phlock_sts;
        u32 phlock_en;
+       u32 phlock_cnt;
        u32 frqlock_sts;
        /*u32 frqlock_stable_cnt;*/
        u32 ss_sts;
@@ -169,6 +170,8 @@ extern unsigned int vlock_en;
 extern unsigned int vecm_latch_flag;
 /*extern void __iomem *amvecm_hiu_reg_base;*/
 extern unsigned int probe_ok;
+extern u32 phase_en_after_frqlock;
+extern u32 vlock_ss_en;
 
 extern void lcd_ss_enable(bool flag);
 extern unsigned int lcd_ss_status(void);