vlock: optimize vlock process for interlace input [1/1]
authorDezhi Kong <dezhi.kong@amlogic.com>
Tue, 30 Oct 2018 09:30:48 +0000 (17:30 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Fri, 9 Nov 2018 11:50:57 +0000 (04:50 -0700)
PD#SWPL-743

Problem:
The picthre is shaking when press DVD remote
control in AV source

Solution:
add delay work for vlock process interlace input

Verify:
T962X-R311

Change-Id: Ic2ed077e0684ecc6b0990336e7a4ab7022931886
Signed-off-by: Dezhi Kong <dezhi.kong@amlogic.com>
drivers/amlogic/media/enhancement/amvecm/amvecm.c
drivers/amlogic/media/enhancement/amvecm/vlock.c
drivers/amlogic/media/enhancement/amvecm/vlock.h
drivers/amlogic/media/vin/tvin/vdin/vdin_drv.c
drivers/amlogic/media/vin/tvin/vdin/vdin_drv.h

index e3b8d63..92e95b5 100644 (file)
@@ -570,6 +570,8 @@ static ssize_t amvecm_vlock_show(struct class *cla,
        len += sprintf(buf+len,
                "echo vlock_line_limit val(D) > /sys/class/amvecm/vlock\n");
        len += sprintf(buf+len,
+               "echo vlock_support 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");
@@ -666,6 +668,11 @@ static ssize_t amvecm_vlock_store(struct class *cla,
                        return -EINVAL;
                temp_val = val;
                sel = VLOCK_LINE_LIMIT;
+       } else if (!strncmp(parm[0], "vlock_support", 13)) {
+               if (kstrtol(parm[1], 10, &val) < 0)
+                       return -EINVAL;
+               temp_val = val;
+               sel = VLOCK_SUPPORT;
        } else if (!strncmp(parm[0], "enable", 6)) {
                vecm_latch_flag |= FLAG_VLOCK_EN;
        } else if (!strncmp(parm[0], "disable", 7)) {
index 09b9ad7..8ce8c0c 100644 (file)
@@ -52,10 +52,10 @@ static unsigned int vlock_delta_limit = 2;
 static unsigned int vlock_pll_m_limit = 1;
 /*for 24MHZ clock, 50hz input, delta value (10) of(0x3011-0x3012) == 0.001HZ */
 static unsigned int vlock_delta_cnt_limit = 10;
-static unsigned int vlock_pll_stable_flag;
+/*hdmi support enable default,cvbs support not good,need debug with vlsi*/
+static unsigned int vlock_support = (VLOCK_SUPPORT_HDMI | VLOCK_SUPPORT_CVBS);
 static unsigned int vlock_enc_stable_flag;
 static unsigned int vlock_pll_stable_cnt;
-static unsigned int vlock_pll_stable_limit = 600;/*10s for 60hz input*/
 static unsigned int vlock_pll_adj_limit;
 static unsigned int vlock_pll_val_last;
 static unsigned int vlock_intput_type;
@@ -171,10 +171,12 @@ static unsigned int vlock_check_input_hz(struct vframe_s *vf)
        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) {
+       else if ((vf->source_type == VFRAME_SOURCE_TYPE_HDMI) &&
+               (vlock_support & VLOCK_SUPPORT_HDMI)) {
                if (duration != 0)
                        ret_hz = (96000 + duration/2)/duration;
-       } else if (vf->source_type == VFRAME_SOURCE_TYPE_CVBS) {
+       } else if ((vf->source_type == VFRAME_SOURCE_TYPE_CVBS) &&
+               (vlock_support & VLOCK_SUPPORT_CVBS)) {
                if (vf->source_mode == VFRAME_SOURCE_MODE_NTSC)
                        ret_hz = 60;
                else if ((vf->source_mode == VFRAME_SOURCE_MODE_PAL) ||
@@ -417,7 +419,8 @@ void vlock_vmode_check(void)
                hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
        vinfo = get_current_vinfo();
        vlock_vmode_changed = 0;
-       if (vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE) {
+       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);
@@ -533,7 +536,6 @@ static void vlock_disable_step1(void)
                vlock_mode |= VLOCK_MODE_MANUAL_PLL;
        }
        vlock_pll_stable_cnt = 0;
-       vlock_pll_stable_flag = 0;
        vlock_enc_stable_flag = 0;
 }
 
@@ -585,7 +587,6 @@ static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo,
        vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
        vlock_pll_stable_cnt = 0;
        vlock_log_cnt = 0;
-       vlock_pll_stable_flag = 0;
        vlock_enc_stable_flag = 0;
 }
 
@@ -929,6 +930,11 @@ static void vlock_enable_step3_pll(void)
                ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
        oa = READ_VPP_REG(VPU_VLOCK_RO_VS_O_DIST);
        abs_cnt = abs(ia - oa);
+       if (abs_cnt > (oa / 3)) {
+               if (vlock_debug & VLOCK_DEBUG_INFO)
+                       pr_info("%s:vlock input cnt abnormal!!\n", __func__);
+               return;
+       }
        /*frac*/
        amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
        abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff));
@@ -950,8 +956,6 @@ static void vlock_enable_step3_pll(void)
                vlock_pll_stable_cnt++;
        else
                vlock_pll_stable_cnt = 0;
-       if (vlock_pll_stable_flag++ > VLOCK_PLL_STABLE_CNT)
-               vlock_pll_stable_flag = VLOCK_PLL_STABLE_CNT;
        /*m*/
        amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
        abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (pre_hiu_reg_m & 0x1ff));
@@ -973,7 +977,7 @@ static void vlock_enable_step3_pll(void)
                vlock_pll_stable_cnt = 0;
 }
 /* won't change this function internal seqence,
- * if really need change,please be carefull
+ * if really need change,please be carefull and check with vlsi
  */
 void amve_vlock_process(struct vframe_s *vf)
 {
@@ -1088,7 +1092,7 @@ void amve_vlock_process(struct vframe_s *vf)
                                (vlock_mode &
                                VLOCK_MODE_MANUAL_MIX_PLL_ENC) &&
                                (vlock_pll_stable_cnt >
-                               vlock_pll_stable_limit)) {
+                               VLOCK_PLL_STABLE_LIMIT)) {
                                vlock_mode &= ~VLOCK_MODE_MANUAL_MIX_PLL_ENC;
                                vlock_mode |= VLOCK_MODE_MANUAL_SOFT_ENC;
                                vlock_state = VLOCK_STATE_ENABLE_FORCE_RESET;
@@ -1201,6 +1205,9 @@ void vlock_param_set(unsigned int val, enum vlock_param_e sel)
        case VLOCK_LINE_LIMIT:
                vlock_line_limit = val;
                break;
+       case VLOCK_SUPPORT:
+               vlock_support = val;
+               break;
        default:
                pr_info("%s:unknown vlock param:%d\n", __func__, sel);
                break;
@@ -1235,9 +1242,8 @@ void vlock_status(void)
        pr_info("vlock_capture_limit:0x%x\n", vlock_capture_limit);
        pr_info("vlock_line_limit:%d\n", vlock_line_limit);
        pr_info("vlock_pll_stable_cnt:%d\n", vlock_pll_stable_cnt);
-       pr_info("vlock_pll_stable_limit:%d\n", vlock_pll_stable_limit);
        pr_info("vlock_enc_adj_limit:%d\n", vlock_enc_adj_limit);
-       pr_info("vlock_pll_stable_flag:%d\n", vlock_pll_stable_flag);
+       pr_info("vlock_support:%d\n", vlock_support);
        pr_info("vlock_enc_stable_flag:%d\n", vlock_enc_stable_flag);
        pr_info("vlock_intput_type:%d\n", vlock_intput_type);
        pr_info("vlock_pll_adj_limit:%d\n", vlock_pll_adj_limit);
index 513c266..96784fb 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/10/16a"
+#define VLOCK_VER "Ref.2018/11/07a"
 
 #define VLOCK_REG_NUM  33
 
@@ -55,6 +55,7 @@ enum vlock_param_e {
        VLOCK_SYNC_LIMIT_FLAG,
        VLOCK_DIS_CNT_NO_VF_LIMIT,
        VLOCK_LINE_LIMIT,
+       VLOCK_SUPPORT,
        VLOCK_PARAM_MAX,
 };
 
@@ -85,7 +86,11 @@ extern void vlock_log_print(void);
 
 #define XTAL_VLOCK_CLOCK   24000000/*vlock use xtal clock*/
 
-#define VLOCK_PLL_STABLE_CNT   180/*vlock pll stabel cnt limit*/
+#define VLOCK_SUPPORT_HDMI (1 << 0)
+#define VLOCK_SUPPORT_CVBS (1 << 1)
+
+/*10s for 60hz input,vlock pll stabel cnt limit*/
+#define VLOCK_PLL_STABLE_LIMIT 600
 #define VLOCK_ENC_STABLE_CNT   180/*vlock enc stabel cnt limit*/
 #define VLOCK_PLL_ADJ_LIMIT 9/*vlock pll adj limit(0x300a default)*/
 
index 0b7875b..74993dc 100644 (file)
@@ -1195,6 +1195,7 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
        enum tvin_trans_fmt trans_fmt;
        struct tvin_sig_property_s *prop, *pre_prop;
        long long *clk_array;
+       long long vlock_delay_jiffies, vlock_t1;
 
        /* debug interrupt interval time
         *
@@ -1313,8 +1314,14 @@ 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);
+
+       if (devp->duration) {
+               vlock_delay_jiffies = func_div(96000, devp->duration);
+               vlock_t1 = func_div(HZ, vlock_delay_jiffies);
+               vlock_delay_jiffies = func_div(vlock_t1, 4);
+       } else
+               vlock_delay_jiffies = msecs_to_jiffies(5);
+       schedule_delayed_work(&devp->vlock_dwork, vlock_delay_jiffies);
 
        /* ignore the unstable signal */
        state = tvin_get_sm_status(devp->index);
@@ -1777,6 +1784,23 @@ static void vdin_dv_dwork(struct work_struct *work)
        cancel_delayed_work(&devp->dv.dv_dwork);
 }
 
+/*ensure vlock mux swith avoid vlock vsync region*/
+static void vdin_vlock_dwork(struct work_struct *work)
+{
+       struct delayed_work *dwork = to_delayed_work(work);
+       struct vdin_dev_s *devp =
+               container_of(dwork, struct vdin_dev_s, vlock_dwork);
+
+       if (!devp || !devp->frontend || !devp->curr_wr_vfe) {
+               pr_info("%s, dwork error !!!\n", __func__);
+               return;
+       }
+       vdin_vlock_input_sel(devp->curr_field_type,
+               devp->curr_wr_vfe->vf.source_type);
+
+       cancel_delayed_work(&devp->vlock_dwork);
+}
+
 /*function:open device
  *     1.request irq to open device configure vdinx
  *     2.disable irq until vdin is configured completely
@@ -2649,6 +2673,7 @@ static int vdin_drv_probe(struct platform_device *pdev)
        vdevp->vdin_dev_ssize = sizeof(struct vdin_dev_s);
        vdevp->canvas_config_mode = canvas_config_mode;
        INIT_DELAYED_WORK(&vdevp->dv.dv_dwork, vdin_dv_dwork);
+       INIT_DELAYED_WORK(&vdevp->vlock_dwork, vdin_vlock_dwork);
 
        vdin_debugfs_init(vdevp);/*2018-07-18 add debugfs*/
        pr_info("%s: driver initialized ok\n", __func__);
@@ -2674,9 +2699,12 @@ fail_kzalloc_vdev:
  */
 static int vdin_drv_remove(struct platform_device *pdev)
 {
+       int ret;
+
        struct vdin_dev_s *vdevp;
        vdevp = platform_get_drvdata(pdev);
 
+       ret = cancel_delayed_work(&vdevp->vlock_dwork);
 #ifdef CONFIG_AML_RDMA
        rdma_unregister(vdevp->rdma_handle);
 #endif
index 2e1f5a6..43e719e 100644 (file)
@@ -45,7 +45,7 @@
 #include "vdin_vf.h"
 #include "vdin_regs.h"
 
-#define VDIN_VER "Ref.2018/09/29"
+#define VDIN_VER "Ref.2018/11/07a"
 
 /*the counter of vdin*/
 #define VDIN_MAX_DEVS                  2
@@ -191,7 +191,7 @@ struct vdin_dev_s {
        struct tvin_sig_property_s prop;
        struct vframe_provider_s vprov;
        struct vdin_dv_s dv;
-
+       struct delayed_work vlock_dwork;
        struct vdin_afbce_s *afbce_info;
 
         /* 0:from gpio A,1:from csi2 , 2:gpio B*/