summaryrefslogtreecommitdiff
authorDezhi 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)
commit5a3e64d40eac3f2e49a3e342c9432a0c0524601a (patch)
tree84b21f90275a676c5f2c4de9229efa7f8d154607
parent040d86e02d6380f8bced1e9decb5dd6e1e241fed (diff)
downloadcommon-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>
Diffstat
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amvecm.c8
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/vlock.c90
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/vlock.h6
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