author | Dezhi Kong <dezhi.kong@amlogic.com> | 2018-10-15 06:44:05 (GMT) |
---|---|---|
committer | Dezhi Kong <dezhi.kong@amlogic.com> | 2018-10-18 03:22:31 (GMT) |
commit | 5a3e64d40eac3f2e49a3e342c9432a0c0524601a (patch) | |
tree | 84b21f90275a676c5f2c4de9229efa7f8d154607 | |
parent | 040d86e02d6380f8bced1e9decb5dd6e1e241fed (diff) | |
download | common-5a3e64d40eac3f2e49a3e342c9432a0c0524601a.zip common-5a3e64d40eac3f2e49a3e342c9432a0c0524601a.tar.gz common-5a3e64d40eac3f2e49a3e342c9432a0c0524601a.tar.bz2 |
vlock: fix issue of hdmitx output timing swith [1/1]
PD#174283
Problem:
The display turned blank / black on switching HDMI input sources
Solution:
optimize timing swith check condition
Verify:
verified by r321 board in Android P
pushed to google partner server
Change-Id: Icf34f74e43a5633c39c6547354296d0ca1d3e77e
Signed-off-by: Dezhi Kong <dezhi.kong@amlogic.com>
-rw-r--r-- | drivers/amlogic/media/enhancement/amvecm/amvecm.c | 8 | ||||
-rw-r--r-- | drivers/amlogic/media/enhancement/amvecm/vlock.c | 90 | ||||
-rw-r--r-- | drivers/amlogic/media/enhancement/amvecm/vlock.h | 6 |
3 files changed, 54 insertions, 50 deletions
diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index b1cf9ac..6f5dc9e 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -4743,6 +4743,11 @@ static struct notifier_block aml_lcd_gamma_nb = { .notifier_call = aml_lcd_gamma_notifier, }; #endif + +static struct notifier_block vlock_notifier_nb = { + .notifier_call = vlock_notify_callback, +}; + static int aml_vecm_probe(struct platform_device *pdev) { int ret = 0; @@ -4784,6 +4789,9 @@ static int aml_vecm_probe(struct platform_device *pdev) if (ret) pr_info("register aml_lcd_gamma_notifier failed\n"); #endif + /* register vout client */ + vout_register_client(&vlock_notifier_nb); + /* #if (MESON_CPU_TYPE == MESON_CPU_TYPE_MESONG9TV) */ 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/vlock.c b/drivers/amlogic/media/enhancement/amvecm/vlock.c index 9e47876..58708c1 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.c +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.c @@ -71,7 +71,6 @@ static unsigned int vlock_dynamic_adjust = 1; static unsigned int vlock_sync_limit_flag; static unsigned int vlock_state = VLOCK_STATE_NULL;/*1/2/3:vlock step*/ -static enum vmode_e pre_vmode = VMODE_INIT_NULL; static enum vframe_source_type_e pre_source_type = VFRAME_SOURCE_TYPE_OTHERS; static enum vframe_source_mode_e pre_source_mode = @@ -79,8 +78,8 @@ static enum vframe_source_mode_e pre_source_mode = static unsigned int pre_input_freq; static unsigned int pre_output_freq; static unsigned int vlock_dis_cnt; -static char pre_vout_mode[64]; static bool vlock_vmode_changed; +static unsigned int vlock_vmode_change_status; static unsigned int pre_hiu_reg_m; static unsigned int pre_hiu_reg_frac; static signed int pre_enc_max_line; @@ -90,8 +89,6 @@ static unsigned int enc_max_pixel_addr; static unsigned int enc_video_mode_addr; static unsigned int enc_video_mode_adv_addr; static unsigned int enc_max_line_switch_addr; -static unsigned int pre_video_clk; - static unsigned int vlock_dis_cnt_no_vf; static unsigned int vlock_dis_cnt_no_vf_limit = 5; @@ -410,8 +407,7 @@ static void vlock_setting(struct vframe_s *vf, void vlock_vmode_check(void) { const struct vinfo_s *vinfo; - unsigned int t0, t1, hiu_reg_addr, cur_video_clk; - char cur_vout_mode[64]; + unsigned int t0, t1, hiu_reg_addr; if (vlock_en == 0) return; @@ -421,35 +417,13 @@ void vlock_vmode_check(void) hiu_reg_addr = HHI_HDMI_PLL_CNTL2; vinfo = get_current_vinfo(); vlock_vmode_changed = 0; - cur_video_clk = vinfo->video_clk; - memset(cur_vout_mode, 0, sizeof(cur_vout_mode)); - if ((vinfo->name == NULL) || - (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_vmode_change_status == VOUT_EVENT_MODE_CHANGE) { if (vlock_mode & (VLOCK_MODE_MANUAL_PLL | VLOCK_MODE_AUTO_PLL)) { amvecm_hiu_reg_read(hiu_reg_addr, &t0); amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &t1); - if (cur_video_clk != pre_video_clk) { - pre_hiu_reg_frac = t0 & 0xfff; - pre_hiu_reg_m = t1 & 0x1ff; - pre_video_clk = cur_video_clk; - } else { - if ((t0 & 0xfff) != pre_hiu_reg_frac) { - t0 = (t0 & 0xfffff000) | - (pre_hiu_reg_frac & 0xfff); - amvecm_hiu_reg_write(hiu_reg_addr, t0); - } - if (((t1 & 0x1ff) != pre_hiu_reg_m) && - (pre_hiu_reg_m != 0)) { - t1 = (t1 & 0xfffffe00) | - (pre_hiu_reg_m & 0x1ff); - amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, - t1); - } - } + pre_hiu_reg_frac = t0 & 0xfff; + pre_hiu_reg_m = t1 & 0x1ff; } if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | VLOCK_MODE_AUTO_ENC | @@ -495,11 +469,7 @@ void vlock_vmode_check(void) vinfo->vtotal + 1; vlock_capture_limit <<= 12; } - if (vlock_debug & VLOCK_DEBUG_INFO) - pr_info("[%s]:vout mode changed:%s==>%s\n", - __func__, pre_vout_mode, cur_vout_mode); - memset(pre_vout_mode, 0, sizeof(pre_vout_mode)); - strcpy(pre_vout_mode, cur_vout_mode); + vlock_vmode_change_status = 0; vlock_vmode_changed = 1; } } @@ -553,8 +523,6 @@ static void vlock_disable_step1(void) 0x1fff, 0, 13); } vlock_dis_cnt = vlock_dis_cnt_limit; - memset(pre_vout_mode, 0, sizeof(pre_vout_mode)); - pre_vmode = VMODE_INIT_NULL; pre_source_type = VFRAME_SOURCE_TYPE_OTHERS; pre_source_mode = VFRAME_SOURCE_MODE_OTHERS; pre_input_freq = 0; @@ -601,13 +569,12 @@ static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo, if (vlock_debug & VLOCK_DEBUG_INFO) { pr_info("%s:vmode/source_type/source_mode/input_freq/output_freq:\n", __func__); - pr_info("\t%d/%d/%d/%d/%d=>%d/%d/%d/%d/%d\n", - pre_vmode, pre_source_type, pre_source_mode, + pr_info("\t%d/%d/%d/%d=>%d/%d/%d/%d\n", + pre_source_type, pre_source_mode, pre_input_freq, pre_output_freq, - vinfo->mode, vf->source_type, vf->source_mode, + vf->source_type, vf->source_mode, input_hz, output_hz); } - pre_vmode = vinfo->mode; pre_source_type = vf->source_type; pre_source_mode = vf->source_mode; pre_input_freq = input_hz; @@ -1051,9 +1018,15 @@ void amve_vlock_process(struct vframe_s *vf) __func__); return; } + if (vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE_PRE) { + vlock_enable(0); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s]auto disable vlock module for vmode change pre case!!!\n", + __func__); + return; + } vlock_vmode_check(); - if ((vinfo->mode != pre_vmode) || - (vf->source_type != pre_source_type) || + if ((vf->source_type != pre_source_type) || (vf->source_mode != pre_source_mode) || (input_hz != pre_input_freq) || (output_hz != pre_output_freq) || @@ -1116,8 +1089,6 @@ void amve_vlock_process(struct vframe_s *vf) VLOCK_MODE_MANUAL_MIX_PLL_ENC) && (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_MIX_PLL_ENC; vlock_mode |= VLOCK_MODE_MANUAL_SOFT_ENC; vlock_state = VLOCK_STATE_ENABLE_FORCE_RESET; @@ -1250,13 +1221,11 @@ void vlock_status(void) pr_info("vlock_dynamic_adjust:%d\n", vlock_dynamic_adjust); pr_info("vlock_state:%d\n", vlock_state); pr_info("vlock_sync_limit_flag:%d\n", vlock_sync_limit_flag); - pr_info("pre_vmode:%d\n", pre_vmode); pr_info("pre_hiu_reg_m:0x%x\n", pre_hiu_reg_m); pr_info("pre_hiu_reg_frac:0x%x\n", pre_hiu_reg_frac); pr_info("pre_enc_max_line:0x%x\n", pre_enc_max_line); pr_info("pre_enc_max_pixel:0x%x\n", pre_enc_max_pixel); pr_info("vlock_dis_cnt:%d\n", vlock_dis_cnt); - pr_info("pre_vout_mode:%s\n", pre_vout_mode); pr_info("vlock_dis_cnt_no_vf:%d\n", vlock_dis_cnt_no_vf); pr_info("vlock_dis_cnt_no_vf_limit:%d\n", vlock_dis_cnt_no_vf_limit); pr_info("enc_max_line_addr:0x%x\n", enc_max_line_addr); @@ -1356,5 +1325,30 @@ void vlock_param_config(struct device_node *node) vlock_mode |= VLOCK_MODE_MANUAL_PLL; } } + +int vlock_notify_callback(struct notifier_block *block, unsigned long cmd, + void *para) +{ + const struct vinfo_s *vinfo; + + vinfo = get_current_vinfo(); + if (!vinfo) { + pr_info("current vinfo NULL\n"); + return -1; + } + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("current vmode=%s, vinfo w=%d,h=%d, cmd: 0x%lx\n", + vinfo->name, vinfo->width, vinfo->height, cmd); + switch (cmd) { + case VOUT_EVENT_MODE_CHANGE_PRE: + case VOUT_EVENT_MODE_CHANGE: + vlock_vmode_change_status = cmd; + break; + default: + break; + } + return 0; +} + /*video lock end*/ diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.h b/drivers/amlogic/media/enhancement/amvecm/vlock.h index 68fa2b2..433e8c1 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.h +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.h @@ -17,13 +17,13 @@ #ifndef __AM_VLOCK_H #define __AM_VLOCK_H - +#include <linux/notifier.h> #include <linux/device.h> #include <linux/of.h> #include <linux/amlogic/media/vfm/vframe.h> #include "linux/amlogic/media/amvecm/ve.h" -#define VLOCK_VER "Ref.2018/09/04a" +#define VLOCK_VER "Ref.2018/10/16a" #define VLOCK_REG_NUM 33 @@ -111,5 +111,7 @@ extern int amvecm_hiu_reg_write(unsigned int reg, unsigned int val); extern void vdin_vlock_input_sel(unsigned int type, enum vframe_source_type_e source_type); extern void vlock_param_config(struct device_node *node); +extern int vlock_notify_callback(struct notifier_block *block, + unsigned long cmd, void *para); #endif |