vpp: fix interlace out issue
authorDezhi Kong <dezhi.kong@amlogic.com>
Fri, 18 Aug 2017 02:23:18 +0000 (10:23 +0800)
committerJianxin Pan <jianxin.pan@amlogic.com>
Mon, 21 Aug 2017 03:17:22 +0000 (20:17 -0700)
PD#145318: vpp: fix interlace out issue

Change-Id: I623bbaf0b0795029ca689a81cf10c274afaa1fc3
Signed-off-by: Dezhi Kong <dezhi.kong@amlogic.com>
drivers/amlogic/media/enhancement/amvecm/amvecm.c
drivers/amlogic/media/video_sink/video.c
drivers/amlogic/media/video_sink/vpp.c
include/linux/amlogic/media/video_sink/vpp.h

index 2c09cef..f6aa0f2 100644 (file)
@@ -2745,6 +2745,98 @@ static ssize_t amvecm_dv_mode_store(struct class *cla,
        return count;
 }
 
+static const char *amvecm_reg_usage_str = {
+       "Usage:\n"
+       "echo rv addr(H) > /sys/class/amvecm/reg;\n"
+       "echo rc addr(H) > /sys/class/amvecm/reg;\n"
+       "echo rh addr(H) > /sys/class/amvecm/reg; read hiu reg\n"
+       "echo wv addr(H) value(H) > /sys/class/amvecm/reg; write vpu reg\n"
+       "echo wc addr(H) value(H) > /sys/class/amvecm/re; write cbus reg\n"
+       "echo wh addr(H) value(H) > /sys/class/amvecm/re; write hiu reg\n"
+       "echo dv|c|h addr(H) num > /sys/class/amvecm/reg; dump reg from addr\n"
+};
+static ssize_t amvecm_reg_show(struct class *cla,
+               struct class_attribute *attr, char *buf)
+{
+       return sprintf(buf, "%s\n", amvecm_reg_usage_str);
+}
+
+static ssize_t amvecm_reg_store(struct class *cla,
+                       struct class_attribute *attr,
+                       const char *buf, size_t count)
+{
+       char *buf_orig, *parm[8] = {NULL};
+       long val = 0;
+       unsigned int reg_addr, reg_val, i;
+
+       if (!buf)
+               return count;
+       buf_orig = kstrdup(buf, GFP_KERNEL);
+       parse_param_amvecm(buf_orig, (char **)&parm);
+       if (!strcmp(parm[0], "rv")) {
+               if (kstrtoul(parm[1], 16, &val) < 0)
+                       return -EINVAL;
+               reg_addr = val;
+               reg_val = READ_VPP_REG(reg_addr);
+               pr_info("VPU[0x%04x]=0x%08x\n", reg_addr, reg_val);
+       } else if (!strcmp(parm[0], "rc")) {
+               if (kstrtoul(parm[1], 16, &val) < 0)
+                       return -EINVAL;
+               reg_addr = val;
+               reg_val = aml_read_cbus(reg_addr);
+               pr_info("CBUS[0x%04x]=0x%08x\n", reg_addr, reg_val);
+       } else if (!strcmp(parm[0], "rh")) {
+               if (kstrtoul(parm[1], 16, &val) < 0)
+                       return -EINVAL;
+               reg_addr = val;
+               amvecm_hiu_reg_read(reg_addr, &reg_val);
+               pr_info("HIU[0x%04x]=0x%08x\n", reg_addr, reg_val);
+       } else if (!strcmp(parm[0], "wv")) {
+               if (kstrtoul(parm[1], 16, &val) < 0)
+                       return -EINVAL;
+               reg_addr = val;
+               if (kstrtoul(parm[2], 16, &val) < 0)
+                       return -EINVAL;
+               reg_val = val;
+               WRITE_VPP_REG(reg_addr, reg_val);
+       } else if (!strcmp(parm[0], "wc")) {
+               if (kstrtoul(parm[1], 16, &val) < 0)
+                       return -EINVAL;
+               reg_addr = val;
+               if (kstrtoul(parm[2], 16, &val) < 0)
+                       return -EINVAL;
+               reg_val = val;
+               aml_write_cbus(reg_addr, reg_val);
+       } else if (!strcmp(parm[0], "wh")) {
+               if (kstrtoul(parm[1], 16, &val) < 0)
+                       return -EINVAL;
+               reg_addr = val;
+               if (kstrtoul(parm[2], 16, &val) < 0)
+                       return -EINVAL;
+               reg_val = val;
+               amvecm_hiu_reg_write(reg_addr, reg_val);
+       } else if (parm[0][0] == 'd') {
+               if (kstrtoul(parm[1], 16, &val) < 0)
+                       return -EINVAL;
+               reg_addr = val;
+               if (kstrtoul(parm[2], 16, &val) < 0)
+                       return -EINVAL;
+               for (i = 0; i < val; i++) {
+                       if (parm[0][1] == 'v')
+                               reg_val = READ_VPP_REG(reg_addr+i);
+                       else if (parm[0][1] == 'c')
+                               reg_val = aml_read_cbus(reg_addr+i);
+                       else if (parm[0][1] == 'h')
+                               amvecm_hiu_reg_read((reg_addr+i),
+                                       &reg_val);
+                       pr_info("REG[0x%04x]=0x%08x\n", (reg_addr+i), reg_val);
+               }
+       } else
+               pr_info("unsupprt cmd!\n");
+
+       return count;
+}
+
 /* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) */
 void init_sharpness(void)
 {
@@ -2874,6 +2966,8 @@ static struct class_attribute amvecm_class_attrs[] = {
                amvecm_vpp_demo_show, amvecm_vpp_demo_store),
        __ATTR(dv_mode, 0644,
                amvecm_dv_mode_show, amvecm_dv_mode_store),
+       __ATTR(reg, 0644,
+               amvecm_reg_show, amvecm_reg_store),
        __ATTR_NULL
 };
 
index b782f91..5933a6c 100644 (file)
@@ -3094,30 +3094,16 @@ static void vd2_set_dcu(struct vframe_s *vf)
 static int detect_vout_type(void)
 {
        int vout_type = VOUT_TYPE_PROG;
-#if DEBUG_TMP
        if ((vinfo) && (vinfo->field_height != vinfo->height)) {
-               switch (vinfo->mode) {
-               case VMODE_480I:
-               case VMODE_480CVBS:
-               case VMODE_576I:
-               case VMODE_576CVBS:
+               if ((vinfo->height == 576) || (vinfo->height == 480))
                        vout_type = (READ_VCBUS_REG(ENCI_INFO_READ) &
                                (1 << 29)) ?
                                VOUT_TYPE_BOT_FIELD : VOUT_TYPE_TOP_FIELD;
-                       break;
-
-               case VMODE_1080I:
-               case VMODE_1080I_50HZ:
-                       /* vout_type = (((READ_VCBUS_REG(ENCI_INFO_READ)*/
-                       /*>> 16) & 0x1fff) < 562) ? */
+               else if (vinfo->height == 1080)
                        vout_type = (((READ_VCBUS_REG(ENCP_INFO_READ) >> 16) &
                                0x1fff) < 562) ?
                                VOUT_TYPE_TOP_FIELD : VOUT_TYPE_BOT_FIELD;
-                       break;
 
-               default:
-                       break;
-               }
 #ifdef CONFIG_AMLOGIC_MEDIA_VSYNC_RDMA
                if (is_vsync_rdma_enable()) {
                        if (vout_type == VOUT_TYPE_TOP_FIELD)
@@ -3127,7 +3113,6 @@ static int detect_vout_type(void)
                }
 #endif
        }
-#endif
        return vout_type;
 }
 
index fdc3456..3b7eb09 100644 (file)
@@ -221,7 +221,7 @@ static const u32 *filter_table[] = {
 };
 
 static int chroma_filter_table[] = {
-       COEF_4POINT_TRIANGLE, /* bicubic */
+       COEF_BICUBIC, /* bicubic */
        COEF_3POINT_TRIANGLE,
        COEF_4POINT_TRIANGLE,
        COEF_4POINT_TRIANGLE, /* bilinear */
@@ -241,6 +241,10 @@ static unsigned int sharpness1_sr2_ctrl_3280 = 0xffffffff;
 MODULE_PARM_DESC(sharpness1_sr2_ctrl_3280, "sharpness1_sr2_ctrl_3280");
 module_param(sharpness1_sr2_ctrl_3280, uint, 0664);
 
+static unsigned int vpp_filter_fix;
+MODULE_PARM_DESC(vpp_filter_fix, "vpp_filter_fix");
+module_param(vpp_filter_fix, uint, 0664);
+
 #define MAX_COEFF_LEVEL 5
 uint num_coeff_level = MAX_COEFF_LEVEL;
 uint vert_coeff_settings[MAX_COEFF_LEVEL] = {
@@ -283,7 +287,8 @@ uint horz_coeff_settings[MAX_COEFF_LEVEL] = {
        /* this setting is most smooth */
 };
 
-static uint coeff(uint *settings, uint ratio, uint phase, bool interlace)
+static uint coeff(uint *settings, uint ratio, uint phase,
+       bool interlace, int combing_lev)
 {
        uint coeff_select = 0;
        uint coeff_type = 0;
@@ -311,8 +316,11 @@ static uint coeff(uint *settings, uint ratio, uint phase, bool interlace)
                 *gxtvbb use dejaggy in SR0 to reduce intelace combing
                 *other chip no dejaggy, need swtich to more blur filter
                 */
-               if (interlace && (coeff_select < 3))
+               if (interlace && (coeff_select < 3) && vpp_filter_fix)
                        coeff_type = COEF_4POINT_BSPLINE;
+               /* use bicubic for static scene */
+               if (combing_lev == 0)
+                       coeff_type = COEF_BICUBIC;
        }
        return coeff_type;
 }
@@ -365,6 +373,14 @@ static u32 skip_policy = 0x81;
 module_param(skip_policy, uint, 0664);
 MODULE_PARM_DESC(skip_policy, "\n skip_policy\n");
 
+unsigned int scaler_filter_cnt_limit = 10;
+MODULE_PARM_DESC(scaler_filter_cnt_limit, "scaler_filter_cnt_limit");
+module_param(scaler_filter_cnt_limit, uint, 0664);
+
+static uint last_vert_filter;
+static uint last_horz_filter;
+static uint scaler_filter_cnt;
+
 static u32 vpp_wide_mode;
 static u32 vpp_zoom_ratio = 100;
 static s32 vpp_zoom_center_x, vpp_zoom_center_y;
@@ -411,6 +427,10 @@ static unsigned int vert_scaler_filter = 0xff;
 module_param(vert_scaler_filter, uint, 0664);
 MODULE_PARM_DESC(vert_scaler_filter, "vert_scaler_filter");
 
+static unsigned int vert_chroma_scaler_filter = 0xff;
+module_param(vert_chroma_scaler_filter, uint, 0664);
+MODULE_PARM_DESC(vert_chroma_scaler_filter, "vert_chroma_scaler_filter");
+
 static unsigned int horz_scaler_filter = 0xff;
 module_param(horz_scaler_filter, uint, 0664);
 MODULE_PARM_DESC(horz_scaler_filter, "horz_scaler_filter");
@@ -1289,7 +1309,8 @@ RESTART:
                                (next_frame_par->vscale_skip_count + 1),
                        1,
                        ((vf->type_original & VIDTYPE_TYPEMASK)
-                               != VIDTYPE_PROGRESSIVE));
+                               != VIDTYPE_PROGRESSIVE),
+                       vf->combing_cur_lev);
        filter->vpp_vert_coeff =
                filter_table[filter->vpp_vert_filter];
 
@@ -1316,7 +1337,8 @@ RESTART:
                        filter->vpp_hf_start_phase_step,
                        next_frame_par->VPP_hf_ini_phase_,
                        ((vf->type_original & VIDTYPE_TYPEMASK)
-                               != VIDTYPE_PROGRESSIVE));
+                               != VIDTYPE_PROGRESSIVE),
+                       vf->combing_cur_lev);
        /*for gxl cvbs out index*/
        if ((vinfo->mode == VMODE_CVBS) &&
                (vinfo->height == 576) &&
@@ -1370,16 +1392,17 @@ RESTART:
                (vert_scaler_filter <= COEF_3D_FILTER)) {
                filter->vpp_vert_coeff = filter_table[vert_scaler_filter];
                filter->vpp_vert_filter = vert_scaler_filter;
-               if (vert_chroma_filter_force_en) {
-                       cur_vert_chroma_filter
-                               = chroma_filter_table[vert_scaler_filter];
+       }
+       if (vert_chroma_filter_force_en &&
+               (vert_chroma_scaler_filter >= COEF_BICUBIC) &&
+               (vert_chroma_scaler_filter <= COEF_3D_FILTER)) {
+               cur_vert_chroma_filter = vert_chroma_scaler_filter;
                        filter->vpp_vert_chroma_coeff
                                = filter_table[cur_vert_chroma_filter];
                        filter->vpp_vert_chroma_filter_en = true;
-               } else {
-                       cur_vert_chroma_filter = COEF_NULL;
-                       filter->vpp_vert_chroma_filter_en = false;
-               }
+       } else {
+               cur_vert_chroma_filter = COEF_NULL;
+               filter->vpp_vert_chroma_filter_en = false;
        }
 
        if ((horz_scaler_filter >= COEF_BICUBIC) &&
@@ -1395,9 +1418,22 @@ RESTART:
                filter->vpp_vert_filter = COEF_3D_FILTER;
        }
 #endif
-
-       cur_vert_filter = filter->vpp_vert_filter;
-       cur_horz_filter = filter->vpp_horz_filter;
+       if ((last_vert_filter != filter->vpp_vert_filter) ||
+               (last_horz_filter != filter->vpp_horz_filter)) {
+               last_vert_filter = filter->vpp_vert_filter;
+               last_horz_filter = filter->vpp_horz_filter;
+               scaler_filter_cnt = 0;
+       } else {
+               scaler_filter_cnt++;
+       }
+       if ((scaler_filter_cnt >= scaler_filter_cnt_limit) &&
+               ((cur_vert_filter != filter->vpp_vert_filter) ||
+               (cur_horz_filter != filter->vpp_horz_filter))) {
+               video_property_notify(1);
+               cur_vert_filter = filter->vpp_vert_filter;
+               cur_horz_filter = filter->vpp_horz_filter;
+               scaler_filter_cnt = scaler_filter_cnt_limit;
+       }
        cur_skip_line = next_frame_par->vscale_skip_count;
 
 #if HAS_VPU_PROT
index 6ae90a7..1cf1d47 100644 (file)
@@ -263,6 +263,7 @@ extern void vpp2_set_zoom_ratio(u32 r);
 
 extern u32 vpp2_get_zoom_ratio(void);
 #endif
+extern int video_property_notify(int flag);
 
 extern int vpp_set_super_scaler_regs(int scaler_path_sel,
        int reg_srscl0_enable,