amvecm: fix atv scaled when switch between different formats [1/3]
authorBencheng Jing <bencheng.jing@amlogic.com>
Fri, 4 Jan 2019 15:03:28 +0000 (23:03 +0800)
committerTao Zeng <tao.zeng@amlogic.com>
Fri, 22 Mar 2019 08:44:16 +0000 (01:44 -0700)
PD#SWPL-3883

Problem:
atv picture flash when switch channel between different formats

Solution:
fresh atv overscan on vync

Verify:
txhd

Change-Id: I74f8e64c12031dbc321675c4b1dbc54adcd3721d
Signed-off-by: Bencheng Jing <bencheng.jing@amlogic.com>
drivers/amlogic/media/enhancement/amvecm/amve.c
drivers/amlogic/media/enhancement/amvecm/amvecm.c
include/linux/amlogic/media/amvecm/amvecm.h

index 6bc63d6..33e1c9d 100644 (file)
@@ -1409,11 +1409,14 @@ void amvecm_fresh_overscan(struct vframe_s *vf)
 {
        unsigned int height = 0;
        unsigned int cur_overscan_timing = 0;
+       unsigned int cur_fmt;
+       unsigned int offset = TIMING_UHD + 1;/*av&atv*/
 
        if (overscan_disable)
                return;
        if (is_dolby_vision_on())
                return;
+
        if (overscan_table[0].load_flag) {
                height = (vf->type & VIDTYPE_COMPRESS) ?
                        vf->compHeight : vf->height;
@@ -1445,19 +1448,57 @@ void amvecm_fresh_overscan(struct vframe_s *vf)
                vf->pic_mode.ve = overscan_table[overscan_timing].ve;
                vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
        }
+       if (overscan_table[offset].load_flag) {
+               cur_fmt = vf->sig_fmt;
+               if (cur_fmt == TVIN_SIG_FMT_CVBS_NTSC_M)
+                       cur_overscan_timing = TIMING_NTST_M;
+               else if (cur_fmt == TVIN_SIG_FMT_CVBS_NTSC_443)
+                       cur_overscan_timing = TIMING_NTST_443;
+               else if (cur_fmt == TVIN_SIG_FMT_CVBS_PAL_I)
+                       cur_overscan_timing = TIMING_PAL_I;
+               else if (cur_fmt == TVIN_SIG_FMT_CVBS_PAL_M)
+                       cur_overscan_timing = TIMING_PAL_M;
+               else if (cur_fmt == TVIN_SIG_FMT_CVBS_PAL_60)
+                       cur_overscan_timing = TIMING_PAL_60;
+               else if (cur_fmt == TVIN_SIG_FMT_CVBS_PAL_CN)
+                       cur_overscan_timing = TIMING_PAL_CN;
+               else if (cur_fmt == TVIN_SIG_FMT_CVBS_SECAM)
+                       cur_overscan_timing = TIMING_SECAM;
+               else if (cur_fmt == TVIN_SIG_FMT_CVBS_NTSC_50)
+                       cur_overscan_timing = TIMING_NTSC_50;
+               else
+                       return;
+               overscan_timing = cur_overscan_timing;
+               overscan_screen_mode =
+                       overscan_table[overscan_timing].screen_mode;
+               vf->pic_mode.AFD_enable =
+                       overscan_table[overscan_timing].afd_enable;
+               vf->pic_mode.screen_mode = overscan_screen_mode;
+               vf->pic_mode.hs = overscan_table[overscan_timing].hs;
+               vf->pic_mode.he = overscan_table[overscan_timing].he;
+               vf->pic_mode.vs = overscan_table[overscan_timing].vs;
+               vf->pic_mode.ve = overscan_table[overscan_timing].ve;
+               vf->ratio_control |= DISP_RATIO_ADAPTED_PICMODE;
+       }
 }
 
 void amvecm_reset_overscan(void)
 {
+       unsigned int offset = TIMING_UHD + 1;/*av&atv*/
+       enum ve_source_input_e source0;
+
+       source0 = overscan_table[0].source;
        if (overscan_disable)
                return;
        if (overscan_timing != TIMING_MAX) {
                overscan_timing = TIMING_MAX;
-               if ((overscan_table[0].source != SOURCE_DTV) &&
-                       (overscan_table[0].source != SOURCE_MPEG)) {
+               if ((source0 != SOURCE_DTV) && (source0 != SOURCE_MPEG))
                        overscan_table[0].load_flag = 0;
+               else if (!atv_source_flg)
+                       overscan_table[offset].load_flag = 0;
+               if ((source0 != SOURCE_DTV) && (source0 != SOURCE_MPEG)
+                       && !atv_source_flg)
                        overscan_screen_mode = 0xff;
-               }
        }
 }
 
index be671c6..c95f1f9 100644 (file)
@@ -119,7 +119,7 @@ static unsigned int pre_hist_height, pre_hist_width;
 static unsigned int pc_mode = 0xff;
 static unsigned int pc_mode_last = 0xff;
 static struct hdr_metadata_info_s vpp_hdr_metadata_s;
-
+unsigned int atv_source_flg;
 /*bit0: brightness
  *bit1: brightness2
  *bit2: saturation_hue
@@ -1334,6 +1334,41 @@ static int gamma_table_compare(struct tcon_gamma_table_s *table1,
        return flag;
 }
 
+static void parse_overscan_table(unsigned int length,
+       struct ve_pq_table_s *amvecm_pq_load_table)
+{
+       unsigned int i;
+       unsigned int offset = TIMING_UHD + 1;
+
+       memset(overscan_table, 0, sizeof(overscan_table));
+       for (i = 0; i < length; i++) {
+               overscan_table[i].load_flag =
+                       (amvecm_pq_load_table[i].src_timing >> 31) & 0x1;
+               overscan_table[i].afd_enable =
+                       (amvecm_pq_load_table[i].src_timing >> 30) & 0x1;
+               overscan_table[i].screen_mode =
+                       (amvecm_pq_load_table[i].src_timing >> 24) & 0x3f;
+               overscan_table[i].source =
+                       (amvecm_pq_load_table[i].src_timing >> 16) & 0xff;
+               overscan_table[i].timing =
+                       amvecm_pq_load_table[i].src_timing & 0xffff;
+               overscan_table[i].hs =
+                       amvecm_pq_load_table[i].value1 & 0xffff;
+               overscan_table[i].he =
+                       (amvecm_pq_load_table[i].value1 >> 16) & 0xffff;
+               overscan_table[i].vs =
+                       amvecm_pq_load_table[i].value2 & 0xffff;
+               overscan_table[i].ve =
+                               (amvecm_pq_load_table[i].value2 >> 16) & 0xffff;
+       }
+       /*because SOURCE_TV is 0,so need to add a flg to check ATV*/
+       if ((overscan_table[offset].load_flag == 1) &&
+               (overscan_table[offset].source == SOURCE_TV))
+               atv_source_flg = 1;
+       else
+               atv_source_flg = 0;
+}
+
 static long amvecm_ioctl(struct file *file,
                unsigned int cmd, unsigned long arg)
 {
@@ -1342,7 +1377,6 @@ static long amvecm_ioctl(struct file *file,
        unsigned int mem_size;
        struct ve_pq_load_s vpp_pq_load;
        struct ve_pq_table_s *vpp_pq_load_table = NULL;
-       int i = 0;
        enum color_primary_e color_pri;
 
        if (debug_amvecm & 2)
@@ -1525,7 +1559,8 @@ static long amvecm_ioctl(struct file *file,
                        break;
                }
                /*check pq_table length copy_from_user*/
-               if (vpp_pq_load.length > PQ_TABLE_MAX_LENGTH) {
+               if ((vpp_pq_load.length > TIMING_MAX) ||
+                       (vpp_pq_load.length <= 0))  {
                        ret = -EFAULT;
                        pr_amvecm_dbg("[amvecm..] pq ioctl length check fail!!\n");
                        break;
@@ -1542,28 +1577,7 @@ static long amvecm_ioctl(struct file *file,
                        pr_amvecm_dbg("[amvecm..] ovescan copy fail!!\n");
                        break;
                }
-               for (i = 0; i < vpp_pq_load.length; i++) {
-                       if (i >= TIMING_MAX)
-                               break;
-                       overscan_table[i].load_flag =
-                               (vpp_pq_load_table[i].src_timing >> 31) & 0x1;
-                       overscan_table[i].afd_enable =
-                               (vpp_pq_load_table[i].src_timing >> 30) & 0x1;
-                       overscan_table[i].screen_mode =
-                               (vpp_pq_load_table[i].src_timing >> 24) & 0x3f;
-                       overscan_table[i].source =
-                               (vpp_pq_load_table[i].src_timing >> 16) & 0xff;
-                       overscan_table[i].timing =
-                               vpp_pq_load_table[i].src_timing & 0xffff;
-                       overscan_table[i].hs =
-                               vpp_pq_load_table[i].value1 & 0xffff;
-                       overscan_table[i].he =
-                               (vpp_pq_load_table[i].value1 >> 16) & 0xffff;
-                       overscan_table[i].vs =
-                               vpp_pq_load_table[i].value2 & 0xffff;
-                       overscan_table[i].ve =
-                               (vpp_pq_load_table[i].value2 >> 16) & 0xffff;
-               }
+               parse_overscan_table(vpp_pq_load.length, vpp_pq_load_table);
                break;
        case AMVECM_IOC_G_DNLP_STATE:
                if (copy_to_user((void __user *)arg,
@@ -4886,7 +4900,7 @@ static ssize_t amvecm_debug_store(struct class *cla,
 {
        char *buf_orig, *parm[8] = {NULL};
        long val = 0;
-       unsigned int mode_sel, color, color_mode;
+       unsigned int mode_sel, color, color_mode, i;
 
        if (!buf)
                return count;
@@ -5286,9 +5300,18 @@ static ssize_t amvecm_debug_store(struct class *cla,
                        cm_luma_bri_con(rd, bri, con, blk_lel);
                        pr_info("cm hist bri_con set success\n");
                }
-       } else {
+       } else if (!strcmp(parm[0], "dump_overscan_table")) {
+               for (i = 0; i < TIMING_MAX; i++) {
+                       pr_info("*****dump overscan_tab[%d]*****\n", i);
+                       pr_info("hs:%d, he:%d, vs:%d, ve:%d, screen_mode:%d, afd:%d, flag:%d.\n",
+                               overscan_table[i].hs, overscan_table[i].he,
+                               overscan_table[i].vs, overscan_table[i].ve,
+                               overscan_table[i].screen_mode,
+                               overscan_table[i].afd_enable,
+                               overscan_table[i].load_flag);
+               }
+       } else
                pr_info("unsupport cmd\n");
-       }
 
        kfree(buf_orig);
        return count;
index 0f5a6ab..118748d 100644 (file)
@@ -135,9 +135,6 @@ enum pq_table_name_e {
        TABLE_NAME_MAX,
 };
 
-/*check pq_table length copy_from_user*/
-#define PQ_TABLE_MAX_LENGTH            10000
-
 #define _VE_CM  'C'
 
 #define AMVECM_IOC_G_HIST_AVG   _IOW(_VE_CM, 0x22, struct ve_hist_s)
@@ -296,11 +293,23 @@ enum ve_source_input_e {
        SOURCE_MAX,
 };
 
+/*pq_timing:
+ *SD/HD/FHD/UHD for DTV/MEPG,
+ *NTST_M/NTST_443/PAL_I/PAL_M/PAL_60/PAL_CN/SECAM/NTST_50 for AV/ATV
+ */
 enum ve_pq_timing_e {
        TIMING_SD = 0,
        TIMING_HD,
        TIMING_FHD,
        TIMING_UHD,
+       TIMING_NTST_M,
+       TIMING_NTST_443,
+       TIMING_PAL_I,
+       TIMING_PAL_M,
+       TIMING_PAL_60,
+       TIMING_PAL_CN,
+       TIMING_SECAM,
+       TIMING_NTSC_50,
        TIMING_MAX,
 };
 
@@ -424,6 +433,8 @@ static inline uint32_t READ_VPP_REG_BITS(uint32_t reg,
 extern signed int vd1_brightness, vd1_contrast;
 extern bool gamma_en;
 extern unsigned int hdr_source_type;
+extern unsigned int atv_source_flg;
+
 
 #define CSC_FLAG_TOGGLE_FRAME  1
 #define CSC_FLAG_CHECK_OUTPUT  2