diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index 2f3e4363ed7f..814587829b6f 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -989,15 +989,6 @@ int amvecm_on_vs( amvecm_fresh_overscan(vf); else amvecm_reset_overscan(); - /* todo:vlock processs only for tv chip */ - if (is_meson_gxtvbb_cpu() || - is_meson_txl_cpu() || is_meson_txlx_cpu() - || is_meson_txhd_cpu()) { - if (vf != NULL) - amve_vlock_process(vf); - else - amve_vlock_resume(); - } /* pq latch process */ amvecm_video_latch(); @@ -4835,19 +4826,7 @@ static int aml_vecm_probe(struct platform_device *pdev) /*config vlock mode*/ /*todo:txlx & g9tv support auto pll,*/ /*but support not good,need vlsi support optimize*/ - if (is_meson_txhd_cpu()) - vlock_mode = VLOCK_MODE_MANUAL_PLL; - else if (is_meson_txlx_cpu() && !is_meson_txlx_package_962E()) { - struct vinfo_s *vinfo = get_current_vinfo(); - - if ((vinfo->fr_adj_type != VOUT_FR_ADJ_HDMI) && - (vinfo->width <= 1920)) - vlock_mode = VLOCK_MODE_MANUAL_SOFT_ENC; - else - vlock_mode = VLOCK_MODE_MANUAL_PLL; - - } else - vlock_mode = VLOCK_MODE_MANUAL_PLL; + vlock_mode = VLOCK_MODE_MANUAL_PLL; if (is_meson_gxtvbb_cpu() || is_meson_txl_cpu() || is_meson_txlx_cpu() || is_meson_txhd_cpu()) diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h b/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h index d06b472e8e6d..96abe2a0fb5c 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h @@ -18,61 +18,58 @@ #ifndef __AMVECM_VLOCK_REGMAP_H #define __AMVECM_VLOCK_REGMAP_H -#include -static struct am_regs_s vlock_enc_setting = { - 20, - { - /* optimize */ - {REG_TYPE_VCBUS, 0x3000, 0xffffffff, 0xE3f50f10 }, - {REG_TYPE_VCBUS, 0x3001, 0xffffffff, 0x41E3c3c }, - {REG_TYPE_VCBUS, 0x3002, 0xffffffff, 0x6000000 }, - {REG_TYPE_VCBUS, 0x3003, 0xffffffff, 0x20680680 }, - {REG_TYPE_VCBUS, 0x3004, 0xffffffff, 0x280280 }, - {REG_TYPE_VCBUS, 0x3005, 0xffffffff, 0x8020000 }, - {REG_TYPE_VCBUS, 0x3006, 0xffffffff, 0x0008000 }, - {REG_TYPE_VCBUS, 0x3007, 0xffffffff, 0x0000000 }, - {REG_TYPE_VCBUS, 0x3008, 0xffffffff, 0x0000000 }, - {REG_TYPE_VCBUS, 0x3009, 0xffffffff, 0x0008000 }, - {REG_TYPE_VCBUS, 0x300a, 0xffffffff, 0x8000000 }, - {REG_TYPE_VCBUS, 0x300b, 0xffffffff, 0x000a000 }, - {REG_TYPE_VCBUS, 0x300c, 0xffffffff, 0xa000000 }, - {REG_TYPE_VCBUS, 0x300d, 0xffffffff, 0x0004000 }, - {REG_TYPE_VCBUS, 0x3010, 0xffffffff, 0x20001000 }, - {REG_TYPE_VCBUS, 0x3016, 0xffffffff, 0x18000 }, - {REG_TYPE_VCBUS, 0x3017, 0xffffffff, 0x01080 }, - {REG_TYPE_VCBUS, 0x301d, 0xffffffff, 0x30501080 }, - {REG_TYPE_VCBUS, 0x301e, 0xffffffff, 0x7 }, - {REG_TYPE_VCBUS, 0x301f, 0xffffffff, 0x6000000 }, - {0} - } +struct vlock_regs_s { + unsigned int addr; + unsigned int val; }; -static struct am_regs_s vlock_pll_setting = { - 20, - { + +#define VLOCK_DEFAULT_REG_SIZE 20 +static struct vlock_regs_s vlock_enc_setting[VLOCK_DEFAULT_REG_SIZE] = { /* optimize */ - {REG_TYPE_VCBUS, 0x3000, 0xffffffff, 0x07f13f1a }, - {REG_TYPE_VCBUS, 0x3001, 0xffffffff, 0x04053c32 }, - {REG_TYPE_VCBUS, 0x3002, 0xffffffff, 0x06000000 }, - {REG_TYPE_VCBUS, 0x3003, 0xffffffff, 0x20780780 }, - {REG_TYPE_VCBUS, 0x3004, 0xffffffff, 0x00000000 }, - {REG_TYPE_VCBUS, 0x3005, 0xffffffff, 0x00080000 }, - {REG_TYPE_VCBUS, 0x3006, 0xffffffff, 0x00070000 }, - {REG_TYPE_VCBUS, 0x3007, 0xffffffff, 0x00000000 }, - {REG_TYPE_VCBUS, 0x3008, 0xffffffff, 0x00000000 }, - {REG_TYPE_VCBUS, 0x3009, 0xffffffff, 0x00100000 }, - {REG_TYPE_VCBUS, 0x300a, 0xffffffff, 0x00008000 }, - {REG_TYPE_VCBUS, 0x300b, 0xffffffff, 0x00100000 }, - {REG_TYPE_VCBUS, 0x300c, 0xffffffff, 0x00000000 }, - {REG_TYPE_VCBUS, 0x300d, 0xffffffff, 0x00004000 }, - {REG_TYPE_VCBUS, 0x3010, 0xffffffff, 0x20001000 }, - {REG_TYPE_VCBUS, 0x3016, 0xffffffff, 0x0003de00 }, - {REG_TYPE_VCBUS, 0x3017, 0xffffffff, 0x00001080 }, - {REG_TYPE_VCBUS, 0x301d, 0xffffffff, 0x30501080 }, - {REG_TYPE_VCBUS, 0x301e, 0xffffffff, 0x00000007 }, - {REG_TYPE_VCBUS, 0x301f, 0xffffffff, 0x06000000 }, - {0} - } + {0x3000, 0xE3f50f10 }, + {0x3001, 0x41E3c3c }, + {0x3002, 0x6000000 }, + {0x3003, 0x20680680 }, + {0x3004, 0x280280 }, + {0x3005, 0x8020000 }, + {0x3006, 0x0008000 }, + {0x3007, 0x0000000 }, + {0x3008, 0x0000000 }, + {0x3009, 0x0008000 }, + {0x300a, 0x8000000 }, + {0x300b, 0x000a000 }, + {0x300c, 0xa000000 }, + {0x300d, 0x0004000 }, + {0x3010, 0x20001000 }, + {0x3016, 0x18000 }, + {0x3017, 0x01080 }, + {0x301d, 0x30501080 }, + {0x301e, 0x7 }, + {0x301f, 0x6000000 }, +}; +static struct vlock_regs_s vlock_pll_setting[VLOCK_DEFAULT_REG_SIZE] = { + /* optimize */ + {0x3000, 0x07f13f1a }, + {0x3001, 0x04053c32 }, + {0x3002, 0x06000000 }, + {0x3003, 0x20780780 }, + {0x3004, 0x00000000 }, + {0x3005, 0x00080000 }, + {0x3006, 0x00070000 }, + {0x3007, 0x00000000 }, + {0x3008, 0x00000000 }, + {0x3009, 0x00100000 }, + {0x300a, 0x00008000 }, + {0x300b, 0x00100000 }, + {0x300c, 0x00000000 }, + {0x300d, 0x00004000 }, + {0x3010, 0x20001000 }, + {0x3016, 0x0003de00 }, + {0x3017, 0x00001080 }, + {0x301d, 0x30501080 }, + {0x301e, 0x00000007 }, + {0x301f, 0x06000000 } }; #endif diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.c b/drivers/amlogic/media/enhancement/amvecm/vlock.c index a01bbe7d36e2..6ec8dec42547 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.c +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.c @@ -45,8 +45,13 @@ unsigned int vlock_en = 1; static unsigned int vlock_adapt; static unsigned int vlock_dis_cnt_limit = 2; static unsigned int vlock_delta_limit = 2; -/* [reg(0x3009) x linemax_num)]>>24 is the limit line of enc mode */ -static signed int vlock_line_limit = 4; +static unsigned int vlock_pll_stable_cnt; +static unsigned int vlock_pll_stable_limit = 180;/*3s for 60hz input*/ +/* [reg(0x3009) x linemax_num)]>>24 is the limit line of enc mode + * change from 4 to 3,for 4 may cause shake issue for 60.3hz input + */ +static signed int vlock_line_limit = 3; +static unsigned int vlock_enc_adj_limit; /* 0x3009 default setting for 2 line(1080p-output) is 0x8000 */ static unsigned int vlock_capture_limit = 0x8000; static unsigned int vlock_debug; @@ -231,6 +236,15 @@ static void vlock_enable(bool enable) enable, 3, 1); } } +static void vlock_hw_reinit(struct vlock_regs_s *vlock_regs, unsigned int len) +{ + unsigned int i; + + if ((vlock_debug & VLOCK_DEBUG_FLUSH_REG_DIS) || (vlock_regs == NULL)) + return; + for (i = 0; i < len; i++) + WRITE_VPP_REG(vlock_regs[i].addr, vlock_regs[i].val); +} static void vlock_setting(struct vframe_s *vf, unsigned int input_hz, unsigned int output_hz) { @@ -242,8 +256,8 @@ static void vlock_setting(struct vframe_s *vf, if ((vlock_mode == VLOCK_MODE_AUTO_ENC) || (vlock_mode == VLOCK_MODE_MANUAL_ENC) || (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) { - if ((vlock_debug & VLOCK_DEBUG_FLUSH_REG_DIS) == 0) - am_set_regmap(&vlock_enc_setting); + /*init default config for enc mode*/ + vlock_hw_reinit(vlock_enc_setting, VLOCK_DEFAULT_REG_SIZE); /*vlock line limit*/ WRITE_VPP_REG(VPU_VLOCK_OUTPUT0_CAPT_LMT, vlock_capture_limit); /* VLOCK_CNTL_EN disable */ @@ -262,7 +276,7 @@ static void vlock_setting(struct vframe_s *vf, 1, 13, 1); WRITE_VPP_REG_BITS(enc_video_mode_adv_addr, 0, 14, 1); } - /* enable to adjust pll */ + /* enable to adjust enc */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 30, 1); /*clear accum1 value*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); @@ -299,8 +313,7 @@ static void vlock_setting(struct vframe_s *vf, if ((vlock_mode == VLOCK_MODE_AUTO_PLL) || (vlock_mode == VLOCK_MODE_MANUAL_PLL)) { /* av pal in,1080p60 hdmi out as default */ - if ((vlock_debug & VLOCK_DEBUG_FLUSH_REG_DIS) == 0) - am_set_regmap(&vlock_pll_setting); + vlock_hw_reinit(vlock_pll_setting, VLOCK_DEFAULT_REG_SIZE); /* *set input & output freq *bit0~7:input freq @@ -345,7 +358,7 @@ static void vlock_setting(struct vframe_s *vf, /*enable vlock to adj pll*/ /* CFG_VID_LOCK_ADJ_EN disable */ WRITE_VPP_REG_BITS(ENCL_MAX_LINE_SWITCH_POINT, 0, 13, 1); - /* disable to adjust pll */ + /* disable to adjust enc */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 30, 1); /* VLOCK_CNTL_EN enable */ vlock_enable(1); @@ -394,7 +407,6 @@ void vlock_vmode_check(void) (strlen(vinfo->name) > sizeof(cur_vout_mode))) return; strcpy(cur_vout_mode, vinfo->name); - if (strcmp(cur_vout_mode, pre_vout_mode) != 0) { if ((vlock_mode == VLOCK_MODE_MANUAL_PLL) || (vlock_mode == VLOCK_MODE_AUTO_PLL)) { @@ -464,7 +476,8 @@ static void vlock_disable_step1(void) vlock_enable(0); vlock_vmode_check(); if ((vlock_mode == VLOCK_MODE_MANUAL_PLL) || - (vlock_mode == VLOCK_MODE_AUTO_PLL)) { + (vlock_mode == VLOCK_MODE_AUTO_PLL) || + (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) { if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) hiu_reg_addr = HHI_HDMI_PLL_CNTL1; else @@ -472,7 +485,7 @@ static void vlock_disable_step1(void) amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value); m_reg_value = tmp_value & 0xfff; if ((m_reg_value != pre_hiu_reg_frac) && - (pre_hiu_reg_m != 0)) { + (pre_hiu_reg_frac != 0)) { tmp_value = (tmp_value & 0xfffff000) | (pre_hiu_reg_frac & 0xfff); amvecm_hiu_reg_write(hiu_reg_addr, tmp_value); @@ -513,6 +526,7 @@ static void vlock_disable_step1(void) pre_input_freq = 0; pre_output_freq = 0; vlock_state = VLOCK_STATE_DISABLE_STEP1_DONE; + vlock_mode = VLOCK_MODE_MANUAL_PLL; } static void vlock_disable_step2(void) @@ -540,6 +554,9 @@ static void vlock_disable_step2(void) static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo, unsigned int input_hz, unsigned int output_hz) { + if (vinfo->vtotal && output_hz) + vlock_enc_adj_limit = (XTAL_VLOCK_CLOCK * vlock_line_limit) / + (vinfo->vtotal * output_hz); vlock_setting(vf, input_hz, output_hz); if (vlock_debug & VLOCK_DEBUG_INFO) { pr_info("%s:vmode/source_type/source_mode/input_freq/output_freq:\n", @@ -559,6 +576,7 @@ static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo, vlock_vmode_changed = 0; vlock_dis_cnt = 0; vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE; + vlock_pll_stable_cnt = 0; vlock_log_cnt = 0; } @@ -691,7 +709,7 @@ static void vlock_enable_step3_enc(void) static void vlock_enable_step3_soft_enc(void) { - unsigned int ia, oa; + unsigned int ia, oa, tmp_value; signed int margin; signed int pixel_adj; signed int err, vdif_err; @@ -714,6 +732,23 @@ static void vlock_enable_step3_soft_enc(void) ia = (READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST) + last_i_vsync + 1) / 2; oa = READ_VPP_REG(VPU_VLOCK_RO_VS_O_DIST); + if ((ia == 0) || (oa == 0)) { + vlock_state = VLOCK_STATE_ENABLE_FORCE_RESET; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("%s:vlock enc work abnormal! force reset vlock\n", + __func__); + return; + } + + /*check enc adj limit*/ + tmp_value = abs(ia - oa); + if (tmp_value > vlock_enc_adj_limit) { + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("%s:vlock enc abs[%d](ia[%d]-oa[%d]) over limit,don't do adj\n", + __func__, tmp_value, ia, oa); + return; + } + if (ia < oa) margin = ia >> 8; else @@ -827,7 +862,7 @@ static void vlock_enable_step3_pll(void) if (m_reg_value == 0) { vlock_state = VLOCK_STATE_ENABLE_FORCE_RESET; if (vlock_debug & VLOCK_DEBUG_INFO) - pr_info("%s:vlock work abnormal! force reset vlock\n", + pr_info("%s:vlock pll work abnormal! force reset vlock\n", __func__); return; } @@ -850,6 +885,11 @@ static void vlock_enable_step3_pll(void) ((m_reg_value & 0xfff) >> 2); amvecm_hiu_reg_write(hiu_reg_addr, tmp_value); } + /*check stable by diff frac*/ + if (abs_val < (2 * vlock_delta_limit)) + vlock_pll_stable_cnt++; + else + vlock_pll_stable_cnt = 0; /*m*/ amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value); abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (tmp_value & 0x1ff)); @@ -862,6 +902,9 @@ static void vlock_enable_step3_pll(void) ((m_reg_value >> 16) & 0x1ff); amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value); } + /*check stable by diff m*/ + if (abs_val) + vlock_pll_stable_cnt = 0; } /* won't change this function internal seqence, * if really need change,please be carefull @@ -964,6 +1007,20 @@ void amve_vlock_process(struct vframe_s *vf) vlock_enable_step3_pll(); else if (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC) vlock_enable_step3_soft_enc(); + /*check stable*/ + if ((vinfo->fr_adj_type != VOUT_FR_ADJ_HDMI) && + (vinfo->width <= 1920) && + !(vlock_debug & VLOCK_DEBUG_PLL2ENC_DIS) && + (vlock_pll_stable_cnt > + vlock_pll_stable_limit)) { + /*reinit pre_vout_mode for trace mode check*/ + memset(pre_vout_mode, 0, sizeof(pre_vout_mode)); + vlock_mode = VLOCK_MODE_MANUAL_SOFT_ENC; + vlock_state = VLOCK_STATE_ENABLE_FORCE_RESET; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s]force reset for switch pll to enc mode!!!\n", + __func__); + } } if (((vlock_mode == VLOCK_MODE_AUTO_PLL) || (vlock_mode == VLOCK_MODE_AUTO_ENC)) && @@ -1012,6 +1069,27 @@ void amve_vlock_resume(void) vlock_enable_step3_soft_enc(); } } + +/*new packed separeted from amvecm_on_vs,avoid the influencec of repeate call, + *which may affect vlock process + */ +void vlock_process(struct vframe_s *vf) +{ + if (probe_ok == 0) + return; + + /* todo:vlock processs only for tv chip */ + if (is_meson_gxtvbb_cpu() || + is_meson_txl_cpu() || is_meson_txlx_cpu() + || is_meson_txhd_cpu()) { + if (vf != NULL) + amve_vlock_process(vf); + else + amve_vlock_resume(); + } +} +EXPORT_SYMBOL(vlock_process); + void vlock_param_set(unsigned int val, enum vlock_param_e sel) { switch (sel) { @@ -1075,6 +1153,9 @@ void vlock_status(void) pr_info("enc_max_line_switch_addr:0x%x\n", enc_max_line_switch_addr); 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); } void vlock_reg_dump(void) { diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.h b/drivers/amlogic/media/enhancement/amvecm/vlock.h index 18b7a0919e76..d7bd385bf6a9 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.h +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.h @@ -84,12 +84,14 @@ extern void vlock_log_print(void); #define VLOCK_DEBUG_ENC_LINE_ADJ_DIS (1 << 2) #define VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS (1 << 3) #define VLOCK_DEBUG_AUTO_MODE_LOG_EN (1 << 4) +#define VLOCK_DEBUG_PLL2ENC_DIS (1 << 5) /* 0:enc;1:pll;2:manual pll */ extern unsigned int vlock_mode; extern unsigned int vlock_en; extern unsigned int vecm_latch_flag; extern void __iomem *amvecm_hiu_reg_base; +extern unsigned int probe_ok; extern void lcd_ss_enable(bool flag); extern unsigned int lcd_ss_status(void); diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 32944105089f..b7b95a465114 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -5234,7 +5234,9 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id) /* determine the out frame is L or R or blank */ judge_3d_fa_out_mode(); } - +#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM) + vlock_process(cur_dispbuf); +#endif while (vf) { if (vpts_expire(cur_dispbuf, vf, toggle_cnt) || show_nosync) { amlog_mask(LOG_MASK_TIMESTAMP, diff --git a/drivers/amlogic/media/vout/vout_serve/vout_serve.c b/drivers/amlogic/media/vout/vout_serve/vout_serve.c index 58f3a069f2d3..fb083f689071 100644 --- a/drivers/amlogic/media/vout/vout_serve/vout_serve.c +++ b/drivers/amlogic/media/vout/vout_serve/vout_serve.c @@ -453,6 +453,7 @@ static ssize_t vout_vinfo_show(struct class *class, " screen_real_height: %d\n" " htotal: %d\n" " vtotal: %d\n" + " fr_adj_type: %d\n" " video_clk: %d\n" " viu_color_fmt: %d\n" " viu_mux: %d\n\n", @@ -461,7 +462,7 @@ static ssize_t vout_vinfo_show(struct class *class, info->aspect_ratio_num, info->aspect_ratio_den, info->sync_duration_num, info->sync_duration_den, info->screen_real_width, info->screen_real_height, - info->htotal, info->vtotal, + info->htotal, info->vtotal, info->fr_adj_type, info->video_clk, info->viu_color_fmt, info->viu_mux); len += sprintf(buf+len, "master_display_info:\n" " present_flag %d\n" diff --git a/include/linux/amlogic/media/amvecm/amvecm.h b/include/linux/amlogic/media/amvecm/amvecm.h index 584325b50fdc..d8c510a7ff74 100644 --- a/include/linux/amlogic/media/amvecm/amvecm.h +++ b/include/linux/amlogic/media/amvecm/amvecm.h @@ -313,6 +313,7 @@ extern int amvecm_on_vs( extern void refresh_on_vs(struct vframe_s *vf); extern void pc_mode_process(void); extern void pq_user_latch_process(void); +extern void vlock_process(struct vframe_s *vf); /* master_display_info for display device */ struct hdr_metadata_info_s {