From 201c4f6c815169af95a6bce9f083f063971b049a Mon Sep 17 00:00:00 2001 From: Bencheng Jing Date: Fri, 4 Jan 2019 23:03:28 +0800 Subject: [PATCH] amvecm: fix atv scaled when switch between different formats [1/3] 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 --- drivers/amlogic/media/enhancement/amvecm/amve.c | 47 +++++++++++++- drivers/amlogic/media/enhancement/amvecm/amvecm.c | 79 +++++++++++++++-------- include/linux/amlogic/media/amvecm/amvecm.h | 17 ++++- 3 files changed, 109 insertions(+), 34 deletions(-) diff --git a/drivers/amlogic/media/enhancement/amvecm/amve.c b/drivers/amlogic/media/enhancement/amvecm/amve.c index 6bc63d6..33e1c9d 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amve.c +++ b/drivers/amlogic/media/enhancement/amvecm/amve.c @@ -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; - } } } diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index be671c6..c95f1f9 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -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; diff --git a/include/linux/amlogic/media/amvecm/amvecm.h b/include/linux/amlogic/media/amvecm/amvecm.h index 0f5a6ab..118748d 100644 --- a/include/linux/amlogic/media/amvecm/amvecm.h +++ b/include/linux/amlogic/media/amvecm/amvecm.h @@ -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 -- 2.7.4