summaryrefslogtreecommitdiff
authorDezhi Kong <dezhi.kong@amlogic.com>2018-07-25 04:25:34 (GMT)
committer Can Cao <can.cao@amlogic.com>2018-10-17 10:36:31 (GMT)
commit32df4d2ea4dc4f2c2a4a230e207007e86c290d49 (patch)
treedebca9aa03dec61f849b23db7272a2c670a11537
parentfb464e5bf0fc083e6c22199e380590662b1611c6 (diff)
downloadcommon-32df4d2ea4dc4f2c2a4a230e207007e86c290d49.zip
common-32df4d2ea4dc4f2c2a4a230e207007e86c290d49.tar.gz
common-32df4d2ea4dc4f2c2a4a230e207007e86c290d49.tar.bz2
vlock: add adj stable check
PD#170985: vlock: add pll adj stable check 1.add pll adj stable check avoid pll m adj 2.add vlock version info 3.add enc adj stable check avoid enc line adj repeate 4.add enc_max_line_switch default config 5.update pll default regmap setting 6.add pll adj value check avoid blink caused by big pll step adj 7.optimize enc pixel adj method 8.add support dts config vlock key parameters 9.move vlock process to start of vsync isr 10.optimize pll for txl vbyone pushed to google partner server Change-Id: Ie6e0aaacd23bfd7178db48e6f0d7bbec426b271f Signed-off-by: Dezhi Kong <dezhi.kong@amlogic.com>
Diffstat
-rw-r--r--arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi12
-rw-r--r--arch/arm64/boot/dts/amlogic/txl_t950_p341.dts13
-rw-r--r--arch/arm64/boot/dts/amlogic/txl_t960_p346.dts13
-rw-r--r--arch/arm64/boot/dts/amlogic/txl_t962_p320.dts13
-rw-r--r--arch/arm64/boot/dts/amlogic/txl_t962_p321.dts13
-rw-r--r--arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts12
-rw-r--r--arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts13
-rw-r--r--arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts12
-rw-r--r--arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts12
-rw-r--r--arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts12
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amvecm.c16
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h2
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/vlock.c308
-rw-r--r--drivers/amlogic/media/enhancement/amvecm/vlock.h22
-rw-r--r--drivers/amlogic/media/video_sink/video.c7
-rw-r--r--drivers/amlogic/media/vout/lcd/lcd_clk_config.c13
-rw-r--r--drivers/amlogic/media/vout/lcd/lcd_clk_config.h4
-rw-r--r--drivers/amlogic/media/vout/lcd/lcd_common.c44
-rw-r--r--drivers/amlogic/media/vout/lcd/lcd_common.h4
-rw-r--r--drivers/amlogic/media/vout/lcd/lcd_debug.c21
-rw-r--r--drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c3
-rw-r--r--drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c3
-rw-r--r--drivers/amlogic/media/vout/lcd/lcd_vout.c28
-rw-r--r--include/linux/amlogic/media/vout/lcd/lcd_notify.h3
-rw-r--r--include/linux/amlogic/media/vout/lcd/lcd_unifykey.h6
-rw-r--r--include/linux/amlogic/media/vout/lcd/lcd_vout.h1
26 files changed, 524 insertions, 86 deletions
diff --git a/arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi
index 274f3e5..4d062ce 100644
--- a/arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi
+++ b/arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi
@@ -399,6 +399,18 @@
0 0 0 100 /*panel power off*/
0xff 0 0 0>; /*ending*/
backlight_index = <3>;
+
+ /*vlock_attr = <1 // vlock_en: 1=enable,0=disable */
+ /* 0x4 // vlock work mode: */
+ /* *bit0:auto ENC */
+ /* *bit1:auto PLL */
+ /* *bit2:manual PLL */
+ /* *bit3:manual ENC */
+ /* *bit4:manual soft ENC */
+ /* *bit5:manual MIX PLL ENC */
+ /* */
+ /* 1 // vlock_pll_m_limit */
+ /* 3>; // vlock_line_limit */
};
}; /* end of lcd */
diff --git a/arch/arm64/boot/dts/amlogic/txl_t950_p341.dts b/arch/arm64/boot/dts/amlogic/txl_t950_p341.dts
index dfce19a..6f3b05f 100644
--- a/arch/arm64/boot/dts/amlogic/txl_t950_p341.dts
+++ b/arch/arm64/boot/dts/amlogic/txl_t950_p341.dts
@@ -414,6 +414,19 @@
gamma_en = <1>;/*1:enabel ;0:disable*/
wb_en = <1>;/*1:enabel ;0:disable*/
cm_en = <1>;/*1:enabel ;0:disable*/
+ wb_sel = <1>;/*1:mtx ;0:gainoff*/
+ vlock_en = <1>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
tuner: tuner {
diff --git a/arch/arm64/boot/dts/amlogic/txl_t960_p346.dts b/arch/arm64/boot/dts/amlogic/txl_t960_p346.dts
index ac81310..c2468b5 100644
--- a/arch/arm64/boot/dts/amlogic/txl_t960_p346.dts
+++ b/arch/arm64/boot/dts/amlogic/txl_t960_p346.dts
@@ -415,6 +415,19 @@
gamma_en = <1>;/*1:enabel ;0:disable*/
wb_en = <1>;/*1:enabel ;0:disable*/
cm_en = <1>;/*1:enabel ;0:disable*/
+ wb_sel = <1>;/*1:mtx ;0:gainoff*/
+ vlock_en = <1>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
tuner: tuner {
diff --git a/arch/arm64/boot/dts/amlogic/txl_t962_p320.dts b/arch/arm64/boot/dts/amlogic/txl_t962_p320.dts
index 92d274f..38fa01d 100644
--- a/arch/arm64/boot/dts/amlogic/txl_t962_p320.dts
+++ b/arch/arm64/boot/dts/amlogic/txl_t962_p320.dts
@@ -406,6 +406,19 @@
gamma_en = <1>;/*1:enabel ;0:disable*/
wb_en = <1>;/*1:enabel ;0:disable*/
cm_en = <1>;/*1:enabel ;0:disable*/
+ wb_sel = <1>;/*1:mtx ;0:gainoff*/
+ vlock_en = <1>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
tuner: tuner {
diff --git a/arch/arm64/boot/dts/amlogic/txl_t962_p321.dts b/arch/arm64/boot/dts/amlogic/txl_t962_p321.dts
index e7d4b78..2cdc361 100644
--- a/arch/arm64/boot/dts/amlogic/txl_t962_p321.dts
+++ b/arch/arm64/boot/dts/amlogic/txl_t962_p321.dts
@@ -405,6 +405,19 @@
gamma_en = <1>;/*1:enabel ;0:disable*/
wb_en = <1>;/*1:enabel ;0:disable*/
cm_en = <1>;/*1:enabel ;0:disable*/
+ wb_sel = <1>;/*1:mtx ;0:gainoff*/
+ vlock_en = <1>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
tuner: tuner {
diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts
index 4adea1c..66c58c0 100644
--- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts
+++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321.dts
@@ -595,6 +595,18 @@
tx_op_color_primary = <0>;
/*1:enabel osd lut 100 table;0:disable*/
cfg_en_osd_100 = <1>;
+ vlock_en = <1>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
amdolby_vision {
compatible = "amlogic, dolby_vision_txlx";
diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts
index 83828a9..12e7d82 100644
--- a/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts
+++ b/arch/arm64/boot/dts/amlogic/txlx_t962e_r321_buildroot.dts
@@ -638,6 +638,19 @@
tx_op_color_primary = <0>;
/*1:enabel osd lut 100 table;0:disable*/
cfg_en_osd_100 = <1>;
+
+ vlock_en = <0>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
amdolby_vision {
compatible = "amlogic, dolby_vision_txlx";
diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts
index ae49a45..621b337 100644
--- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts
+++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts
@@ -584,6 +584,18 @@
wb_en = <1>;/*1:enabel ;0:disable*/
cm_en = <1>;/*1:enabel ;0:disable*/
wb_sel = <1>;/*1:mtx ;0:gainoff*/
+ vlock_en = <1>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
amdolby_vision {
compatible = "amlogic, dolby_vision_txlx";
diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts
index 00e61f6..927f8c9 100644
--- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts
+++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts
@@ -584,6 +584,18 @@
wb_en = <1>;/*1:enabel ;0:disable*/
cm_en = <1>;/*1:enabel ;0:disable*/
wb_sel = <1>;/*1:mtx ;0:gainoff*/
+ vlock_en = <1>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
amdolby_vision {
compatible = "amlogic, dolby_vision_txlx";
diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts
index cc61118..9aed7f5 100644
--- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts
+++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts
@@ -583,6 +583,18 @@
wb_en = <1>;/*1:enabel ;0:disable*/
cm_en = <1>;/*1:enabel ;0:disable*/
wb_sel = <1>;/*1:mtx ;0:gainoff*/
+ vlock_en = <1>;/*1:enable;0:disable*/
+ vlock_mode = <0x4>;
+ /* vlock work mode:
+ *bit0:auto ENC
+ *bit1:auto PLL
+ *bit2:manual PLL
+ *bit3:manual ENC
+ *bit4:manual soft ENC
+ *bit5:manual MIX PLL ENC
+ */
+ vlock_pll_m_limit = <1>;
+ vlock_line_limit = <3>;
};
amdolby_vision {
compatible = "amlogic, dolby_vision_txlx";
diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c
index bf9cd01..b1cf9ac 100644
--- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c
+++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c
@@ -532,6 +532,10 @@ static ssize_t amvecm_vlock_show(struct class *cla,
len += sprintf(buf+len,
"echo vlock_delta_limit val(D) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
+ "echo vlock_pll_m_limit val(D) > /sys/class/amvecm/vlock\n");
+ len += sprintf(buf+len,
+ "echo vlock_delta_cnt_limit val(D) > /sys/class/amvecm/vlock\n");
+ len += sprintf(buf+len,
"echo vlock_debug val(0x111) > /sys/class/amvecm/vlock\n");
len += sprintf(buf+len,
"echo vlock_dynamic_adjust val(0/1) > /sys/class/amvecm/vlock\n");
@@ -601,6 +605,16 @@ static ssize_t amvecm_vlock_store(struct class *cla,
return -EINVAL;
temp_val = val;
sel = VLOCK_DELTA_LIMIT;
+ } else if (!strncmp(parm[0], "vlock_pll_m_limit", 17)) {
+ if (kstrtol(parm[1], 10, &val) < 0)
+ return -EINVAL;
+ temp_val = val;
+ sel = VLOCK_PLL_M_LIMIT;
+ } else if (!strncmp(parm[0], "vlock_delta_cnt_limit", 21)) {
+ if (kstrtol(parm[1], 10, &val) < 0)
+ return -EINVAL;
+ temp_val = val;
+ sel = VLOCK_DELTA_CNT_LIMIT;
} else if (!strncmp(parm[0], "vlock_debug", 11)) {
if (kstrtol(parm[1], 16, &val) < 0)
return -EINVAL;
@@ -4684,6 +4698,8 @@ static void aml_vecm_dt_parse(struct platform_device *pdev)
pr_info("Can't find tx_op_color_primary.\n");
else
tx_op_color_primary = val;
+ /*vlock param config*/
+ vlock_param_config(node);
}
/* init module status */
amvecm_wb_init(wb_en);
diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h b/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h
index 96abe2a..bdd4737 100644
--- a/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h
+++ b/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h
@@ -60,7 +60,7 @@ static struct vlock_regs_s vlock_pll_setting[VLOCK_DEFAULT_REG_SIZE] = {
{0x3007, 0x00000000 },
{0x3008, 0x00000000 },
{0x3009, 0x00100000 },
- {0x300a, 0x00008000 },
+ {0x300a, 0x00600000 },
{0x300b, 0x00100000 },
{0x300c, 0x00000000 },
{0x300d, 0x00004000 },
diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.c b/drivers/amlogic/media/enhancement/amvecm/vlock.c
index 6ec8dec..9e47876 100644
--- a/drivers/amlogic/media/enhancement/amvecm/vlock.c
+++ b/drivers/amlogic/media/enhancement/amvecm/vlock.c
@@ -26,6 +26,9 @@
#include <linux/amlogic/media/vout/vinfo.h>
#include <linux/amlogic/media/vout/vout_notify.h>
#include <linux/io.h>
+#ifdef CONFIG_AMLOGIC_LCD
+#include <linux/amlogic/media/vout/lcd/lcd_notify.h>
+#endif
#include "arch/vpp_regs.h"
#include "vlock.h"
#include "amvecm_vlock_regmap.h"
@@ -45,8 +48,17 @@ 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;
+/*limit vlock pll m adj*/
+static unsigned int vlock_pll_m_limit = 1;
+/*for 24MHZ clock, 50hz input, delta value (10) of(0x3011-0x3012) == 0.001HZ */
+static unsigned int vlock_delta_cnt_limit = 10;
+static unsigned int vlock_pll_stable_flag;
+static unsigned int vlock_enc_stable_flag;
static unsigned int vlock_pll_stable_cnt;
-static unsigned int vlock_pll_stable_limit = 180;/*3s for 60hz input*/
+static unsigned int vlock_pll_stable_limit = 600;/*10s for 60hz input*/
+static unsigned int vlock_pll_adj_limit;
+static unsigned int vlock_pll_val_last;
+static unsigned int vlock_intput_type;
/* [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
*/
@@ -78,6 +90,7 @@ 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;
@@ -215,7 +228,7 @@ static void vlock_enable(bool enable)
amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
if (is_meson_gxtvbb_cpu()) {
- if (vlock_mode == VLOCK_MODE_MANUAL_PLL) {
+ if (vlock_mode & VLOCK_MODE_MANUAL_PLL) {
amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 20, 1);
/*vlsi suggest config:don't enable load signal,
*on gxtvbb this load signal will effect SSG,
@@ -229,7 +242,7 @@ static void vlock_enable(bool enable)
amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6,
enable, 20, 1);
} else if (is_meson_txl_cpu() || is_meson_txlx_cpu()) {
- if (vlock_mode == VLOCK_MODE_MANUAL_PLL)
+ if (vlock_mode & VLOCK_MODE_MANUAL_PLL)
amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5, 0, 3, 1);
else
amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5,
@@ -253,9 +266,9 @@ static void vlock_setting(struct vframe_s *vf,
unsigned int hiu_m_val, hiu_frac_val, temp_value;
amvecm_hiu_reg_write(HHI_VID_LOCK_CLK_CNTL, 0x80);
- if ((vlock_mode == VLOCK_MODE_AUTO_ENC) ||
- (vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
- (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+ if ((vlock_mode & (VLOCK_MODE_AUTO_ENC |
+ VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_MANUAL_SOFT_ENC))) {
/*init default config for enc mode*/
vlock_hw_reinit(vlock_enc_setting, VLOCK_DEFAULT_REG_SIZE);
/*vlock line limit*/
@@ -265,12 +278,14 @@ static void vlock_setting(struct vframe_s *vf,
/* disable to adjust pll */
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 29, 1);
/* CFG_VID_LOCK_ADJ_EN enable */
- if ((vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
- (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+ if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_MANUAL_SOFT_ENC))) {
/*auto vlock off*/
WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
0, 13, 1);
WRITE_VPP_REG_BITS(enc_video_mode_adv_addr, 1, 14, 1);
+ WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
+ pre_enc_max_pixel, 0, 13);
} else {
WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
1, 13, 1);
@@ -289,7 +304,7 @@ static void vlock_setting(struct vframe_s *vf,
*bit8~15:output freq
*/
if ((vf->type_original & VIDTYPE_TYPEMASK) &&
- (vlock_mode != VLOCK_MODE_MANUAL_SOFT_ENC))
+ !(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC))
input_hz = input_hz >> 1;
freq_hz = input_hz | (output_hz << 8);
WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16);
@@ -310,8 +325,8 @@ static void vlock_setting(struct vframe_s *vf,
vlock_latch_en_cnt, 8, 8);
WRITE_VPP_REG_BITS(enc_video_mode_addr, 0, 15, 1);
}
- if ((vlock_mode == VLOCK_MODE_AUTO_PLL) ||
- (vlock_mode == VLOCK_MODE_MANUAL_PLL)) {
+ if ((vlock_mode & (VLOCK_MODE_AUTO_PLL |
+ VLOCK_MODE_MANUAL_PLL))) {
/* av pal in,1080p60 hdmi out as default */
vlock_hw_reinit(vlock_pll_setting, VLOCK_DEFAULT_REG_SIZE);
/*
@@ -354,6 +369,10 @@ static void vlock_setting(struct vframe_s *vf,
+ (hiu_frac_val << 2);
}
WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, reg_value, 0, 21);
+ /*vlock_pll_adj_limit = (reg_value * 0x8000) >> 24;*/
+ vlock_pll_adj_limit = reg_value >> VLOCK_PLL_ADJ_LIMIT;
+ vlock_pll_val_last = ((reg_value & 0x3fff000) << 4) |
+ (reg_value & 0x3fff);
/*enable vlock to adj pll*/
/* CFG_VID_LOCK_ADJ_EN disable */
@@ -391,7 +410,7 @@ static void vlock_setting(struct vframe_s *vf,
void vlock_vmode_check(void)
{
const struct vinfo_s *vinfo;
- unsigned int tmp_value, hiu_reg_addr;
+ unsigned int t0, t1, hiu_reg_addr, cur_video_clk;
char cur_vout_mode[64];
if (vlock_en == 0)
@@ -402,22 +421,39 @@ 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_mode == VLOCK_MODE_MANUAL_PLL) ||
- (vlock_mode == VLOCK_MODE_AUTO_PLL)) {
- amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
- pre_hiu_reg_frac = tmp_value & 0xfff;
- amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
- pre_hiu_reg_m = tmp_value & 0x1ff;
+ 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);
+ }
+ }
}
- if ((vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
- (vlock_mode == VLOCK_MODE_AUTO_ENC) ||
- (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+ if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_AUTO_ENC |
+ VLOCK_MODE_MANUAL_SOFT_ENC))) {
switch (READ_VPP_REG_BITS(VPU_VIU_VENC_MUX_CTRL,
0, 2)) {
case 0:
@@ -475,17 +511,16 @@ static void vlock_disable_step1(void)
/* VLOCK_CNTL_EN disable */
vlock_enable(0);
vlock_vmode_check();
- if ((vlock_mode == VLOCK_MODE_MANUAL_PLL) ||
- (vlock_mode == VLOCK_MODE_AUTO_PLL) ||
- (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+ if ((vlock_mode & (VLOCK_MODE_MANUAL_PLL |
+ VLOCK_MODE_AUTO_PLL |
+ VLOCK_MODE_MANUAL_SOFT_ENC))) {
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
else
hiu_reg_addr = HHI_HDMI_PLL_CNTL2;
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_frac != 0)) {
+ if (m_reg_value != pre_hiu_reg_frac) {
tmp_value = (tmp_value & 0xfffff000) |
(pre_hiu_reg_frac & 0xfff);
amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
@@ -499,24 +534,23 @@ static void vlock_disable_step1(void)
amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
}
}
- if ((vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
- (vlock_mode == VLOCK_MODE_AUTO_ENC) ||
- (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)) {
+ if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_AUTO_ENC |
+ VLOCK_MODE_MANUAL_SOFT_ENC))) {
err_accum = 0;
WRITE_VPP_REG_BITS(enc_video_mode_adv_addr, 0, 14, 1);
enc_max_line = READ_VPP_REG(enc_max_line_addr);
- enc_max_pixel = READ_VPP_REG(enc_max_pixel_addr);
+ enc_max_pixel = READ_VPP_REG_BITS(enc_max_line_switch_addr,
+ 0, 13);
if (!(vlock_debug & VLOCK_DEBUG_ENC_LINE_ADJ_DIS) &&
(enc_max_line != pre_enc_max_line) &&
(pre_enc_max_line != 0) && (enc_max_line_addr != 0))
WRITE_VPP_REG(enc_max_line_addr, pre_enc_max_line);
if (!(vlock_debug & VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS) &&
(enc_max_pixel != pre_enc_max_pixel) &&
- (enc_max_line_addr != 0) && (enc_max_pixel_addr != 0)) {
+ (enc_max_line_switch_addr != 0))
WRITE_VPP_REG_BITS(enc_max_line_switch_addr,
0x1fff, 0, 13);
- WRITE_VPP_REG(enc_max_pixel_addr, pre_enc_max_pixel);
- }
}
vlock_dis_cnt = vlock_dis_cnt_limit;
memset(pre_vout_mode, 0, sizeof(pre_vout_mode));
@@ -526,7 +560,13 @@ 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;
+ if (vlock_mode & VLOCK_MODE_MANUAL_MIX_PLL_ENC) {
+ vlock_mode &= ~VLOCK_MODE_MANUAL_MIX_PLL_ENC;
+ vlock_mode |= VLOCK_MODE_MANUAL_PLL;
+ }
+ vlock_pll_stable_cnt = 0;
+ vlock_pll_stable_flag = 0;
+ vlock_enc_stable_flag = 0;
}
static void vlock_disable_step2(void)
@@ -578,6 +618,8 @@ static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo,
vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;
vlock_pll_stable_cnt = 0;
vlock_log_cnt = 0;
+ vlock_pll_stable_flag = 0;
+ vlock_enc_stable_flag = 0;
}
void vlock_log_start(void)
@@ -784,25 +826,37 @@ static void vlock_enable_step3_soft_enc(void)
line_adj = nT0 >> 14;
- if (line_adj > vlock_line_limit)
- line_adj = vlock_line_limit;
- else if (line_adj < -vlock_line_limit)
- line_adj = -vlock_line_limit;
-
tfrac = nT0 - (line_adj << 14);
pixel_adj = (tfrac * pre_enc_max_pixel + 8192) >> 14;
- if ((pixel_adj + pre_enc_max_pixel) > 0x1fff) {
+ while ((pixel_adj < 0) && (pre_enc_max_pixel > 0)) {
+ line_adj = line_adj - 1;
+ pixel_adj = pre_enc_max_pixel + pixel_adj;
+ }
+
+ while (((pixel_adj + pre_enc_max_pixel) > 0x1fff) &&
+ (pre_enc_max_pixel > 0)) {
line_adj = line_adj + 1;
pixel_adj = pixel_adj - pre_enc_max_pixel;
}
+ if (line_adj > vlock_line_limit)
+ line_adj = vlock_line_limit;
+ else if (line_adj < -vlock_line_limit)
+ line_adj = -vlock_line_limit;
+
pixel_adj &= 0xfffffffe;/*clean bit0*/
- WRITE_VPP_REG(ENCL_VIDEO_MAX_LNCNT, pre_enc_max_line + line_adj);
- WRITE_VPP_REG(ENCL_MAX_LINE_SWITCH_POINT,
- pre_enc_max_pixel + pixel_adj);
+ if (vlock_enc_stable_flag++ > VLOCK_ENC_STABLE_CNT)
+ vlock_enc_stable_flag = VLOCK_ENC_STABLE_CNT;
+ if ((vlock_enc_stable_flag < VLOCK_ENC_STABLE_CNT) &&
+ (!(vlock_debug & VLOCK_DEBUG_ENC_LINE_ADJ_DIS)))
+ WRITE_VPP_REG(ENCL_VIDEO_MAX_LNCNT,
+ pre_enc_max_line + line_adj);
+ if (!(vlock_debug & VLOCK_DEBUG_ENC_PIXEL_ADJ_DIS))
+ WRITE_VPP_REG(ENCL_MAX_LINE_SWITCH_POINT,
+ pre_enc_max_pixel + pixel_adj);
last_i_vsync = READ_VPP_REG(0x3011);
@@ -819,10 +873,32 @@ static void vlock_enable_step3_soft_enc(void)
vlock_log_cnt++;
}
}
-
+/*check pll adj value (0x3020),otherwise may cause blink*/
+static void vlock_pll_adj_limit_check(unsigned int *pll_val)
+{
+ unsigned int m_reg_value, pll_cur, pll_last, pll_ret;
+
+ m_reg_value = *pll_val;
+
+ if (m_reg_value != 0) {
+ pll_cur = ((m_reg_value & 0x3fff0000) >> 4) |
+ (m_reg_value & 0x3fff);
+ pll_last = ((vlock_pll_val_last & 0x3fff0000) >> 4) |
+ (vlock_pll_val_last & 0x3fff);
+ if (abs(pll_cur - pll_last) > vlock_pll_adj_limit) {
+ if (pll_cur > pll_last)
+ pll_ret = pll_last + vlock_pll_adj_limit;
+ else
+ pll_ret = pll_last - vlock_pll_adj_limit;
+ *pll_val = ((pll_ret & 0x3fff000) << 4) |
+ (pll_ret & 0x3fff);
+ }
+ }
+}
static void vlock_enable_step3_pll(void)
{
unsigned int m_reg_value, tmp_value, abs_val, hiu_reg_addr;
+ unsigned int ia, oa, abs_cnt;
if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL)
hiu_reg_addr = HHI_HDMI_PLL_CNTL1;
@@ -854,8 +930,10 @@ static void vlock_enable_step3_pll(void)
m_reg_value = READ_VPP_REG(VPU_VLOCK_RO_M_INT_FRAC);
if (vlock_log_en && (vlock_log_cnt < vlock_log_size)) {
- vlock_log[vlock_log_cnt]->pll_frac = (m_reg_value & 0xfff) >> 2;
- vlock_log[vlock_log_cnt]->pll_m = (m_reg_value >> 16) & 0x1ff;
+ vlock_log[vlock_log_cnt]->pll_frac =
+ (vlock_pll_val_last & 0xfff) >> 2;
+ vlock_log[vlock_log_cnt]->pll_m =
+ (vlock_pll_val_last >> 16) & 0x1ff;
vlock_reg_get();
vlock_log_cnt++;
}
@@ -866,6 +944,9 @@ static void vlock_enable_step3_pll(void)
__func__);
return;
}
+ /*check adjust delta limit*/
+ vlock_pll_adj_limit_check(&m_reg_value);
+
/*vlsi suggest config:don't enable load signal,
*on gxtvbb this load signal will effect SSG,
*which may result in flashes black
@@ -873,6 +954,14 @@ static void vlock_enable_step3_pll(void)
amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value);
if (is_meson_gxtvbb_cpu() && (((tmp_value >> 21) & 0x3) != 2))
amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 2, 21, 2);
+ /*add delta count check*/
+ /*for interlace input need div 2*/
+ if (vlock_intput_type)
+ ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST) / 2;
+ else
+ ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST);
+ oa = READ_VPP_REG(VPU_VLOCK_RO_VS_O_DIST);
+ abs_cnt = abs(ia - oa);
/*frac*/
amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value);
abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff));
@@ -880,30 +969,40 @@ static void vlock_enable_step3_pll(void)
pr_info("vlock frac delta:%d(0x%x,0x%x)\n",
abs_val, ((m_reg_value & 0xfff) >> 2),
(tmp_value & 0xfff));
- if (abs_val >= vlock_delta_limit) {
+ if ((abs_val >= vlock_delta_limit) &&
+ (abs_cnt > vlock_delta_cnt_limit)) {
tmp_value = (tmp_value & 0xfffff000) |
((m_reg_value & 0xfff) >> 2);
amvecm_hiu_reg_write(hiu_reg_addr, tmp_value);
+ vlock_pll_val_last &= 0xffff0000;
+ vlock_pll_val_last |= (m_reg_value & 0xfff);
}
/*check stable by diff frac*/
- if (abs_val < (2 * vlock_delta_limit))
+ if ((abs_val < (2 * vlock_delta_limit)) &&
+ (abs_cnt < vlock_enc_adj_limit))
vlock_pll_stable_cnt++;
else
vlock_pll_stable_cnt = 0;
+ if (vlock_pll_stable_flag++ > VLOCK_PLL_STABLE_CNT)
+ vlock_pll_stable_flag = VLOCK_PLL_STABLE_CNT;
/*m*/
amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value);
- abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (tmp_value & 0x1ff));
+ abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (pre_hiu_reg_m & 0x1ff));
if ((abs_val > vlock_log_delta_m) && (vlock_log_delta_en&(1<<4)))
pr_info("vlock m delta:%d(0x%x,0x%x)\n",
abs_val, ((m_reg_value >> 16) & 0x1ff),
(tmp_value & 0x1ff));
- if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) {
+ if ((abs_val <= vlock_pll_m_limit) &&
+ (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) &&
+ (abs_cnt > vlock_delta_cnt_limit)) {
tmp_value = (tmp_value & 0xfffffe00) |
((m_reg_value >> 16) & 0x1ff);
amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value);
+ vlock_pll_val_last &= 0x0000ffff;
+ vlock_pll_val_last |= (m_reg_value & 0xffff0000);
}
/*check stable by diff m*/
- if (abs_val)
+ if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff))
vlock_pll_stable_cnt = 0;
}
/* won't change this function internal seqence,
@@ -965,14 +1064,16 @@ void amve_vlock_process(struct vframe_s *vf)
(vlock_state >= VLOCK_STATE_ENABLE_STEP1_DONE)) {
vlock_sync_limit_flag++;
if ((vlock_sync_limit_flag <= 3) &&
- (vlock_mode == VLOCK_MODE_MANUAL_ENC)) {
+ ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_MANUAL_PLL)))) {
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);
WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0);
WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0);
}
if ((vlock_sync_limit_flag == 4) &&
- (vlock_mode == VLOCK_MODE_MANUAL_ENC)) {
+ ((vlock_mode & (VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_MANUAL_PLL)))) {
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);
}
@@ -998,32 +1099,35 @@ void amve_vlock_process(struct vframe_s *vf)
(vlock_sync_limit_flag > 5) &&
(vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) &&
(cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) &&
- ((vlock_mode == VLOCK_MODE_MANUAL_PLL) ||
- (vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
- (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC))) {
- if (vlock_mode == VLOCK_MODE_MANUAL_ENC)
+ ((vlock_mode & (VLOCK_MODE_MANUAL_PLL |
+ VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_MANUAL_SOFT_ENC)))) {
+ if (vlock_mode & VLOCK_MODE_MANUAL_ENC)
vlock_enable_step3_enc();
- else if (vlock_mode == VLOCK_MODE_MANUAL_PLL)
+ else if (vlock_mode & VLOCK_MODE_MANUAL_PLL)
vlock_enable_step3_pll();
- else if (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)
+ 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_mode &
+ 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_SOFT_ENC;
+ vlock_mode &= ~VLOCK_MODE_MANUAL_MIX_PLL_ENC;
+ 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",
+ 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)) &&
+ if (((vlock_mode & (VLOCK_MODE_AUTO_PLL |
+ VLOCK_MODE_AUTO_ENC))) &&
vlock_log_en && (vlock_log_cnt < vlock_log_size) &&
(vlock_debug & VLOCK_DEBUG_AUTO_MODE_LOG_EN)) {
vlock_reg_get();
@@ -1058,14 +1162,14 @@ void amve_vlock_resume(void)
(vlock_sync_limit_flag > 5) &&
(vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) &&
(cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) &&
- ((vlock_mode == VLOCK_MODE_MANUAL_PLL) ||
- (vlock_mode == VLOCK_MODE_MANUAL_ENC) ||
- (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC))) {
- if (vlock_mode == VLOCK_MODE_MANUAL_ENC)
+ ((vlock_mode & (VLOCK_MODE_MANUAL_PLL |
+ VLOCK_MODE_MANUAL_ENC |
+ VLOCK_MODE_MANUAL_SOFT_ENC)))) {
+ if (vlock_mode & VLOCK_MODE_MANUAL_ENC)
vlock_enable_step3_enc();
- else if (vlock_mode == VLOCK_MODE_MANUAL_PLL)
+ else if (vlock_mode & VLOCK_MODE_MANUAL_PLL)
vlock_enable_step3_pll();
- else if (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC)
+ else if (vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC)
vlock_enable_step3_soft_enc();
}
}
@@ -1108,6 +1212,12 @@ void vlock_param_set(unsigned int val, enum vlock_param_e sel)
case VLOCK_DELTA_LIMIT:
vlock_delta_limit = val;
break;
+ case VLOCK_PLL_M_LIMIT:
+ vlock_pll_m_limit = val;
+ break;
+ case VLOCK_DELTA_CNT_LIMIT:
+ vlock_delta_cnt_limit = val;
+ break;
case VLOCK_DEBUG:
vlock_debug = val;
break;
@@ -1134,6 +1244,8 @@ void vlock_status(void)
pr_info("vlock_adapt:%d\n", vlock_adapt);
pr_info("vlock_dis_cnt_limit:%d\n", vlock_dis_cnt_limit);
pr_info("vlock_delta_limit:%d\n", vlock_delta_limit);
+ pr_info("vlock_pll_m_limit:%d\n", vlock_pll_m_limit);
+ pr_info("vlock_delta_cnt_limit:%d\n", vlock_delta_cnt_limit);
pr_info("vlock_debug:0x%x\n", vlock_debug);
pr_info("vlock_dynamic_adjust:%d\n", vlock_dynamic_adjust);
pr_info("vlock_state:%d\n", vlock_state);
@@ -1156,6 +1268,12 @@ void vlock_status(void)
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);
+ pr_info("vlock_pll_stable_flag:%d\n", vlock_pll_stable_flag);
+ pr_info("vlock_enc_stable_flag:%d\n", vlock_enc_stable_flag);
+ pr_info("vlock_intput_type:%d\n", vlock_intput_type);
+ pr_info("vlock_pll_adj_limit:%d\n", vlock_pll_adj_limit);
+ pr_info("vlock_pll_val_last:%d\n", vlock_pll_val_last);
+ pr_info("vlock driver version : %s\n", VLOCK_VER);
}
void vlock_reg_dump(void)
{
@@ -1177,10 +1295,11 @@ void vlock_reg_dump(void)
void vdin_vlock_input_sel(unsigned int type,
enum vframe_source_type_e source_type)
{
- type = type & VIDTYPE_TYPEMASK;
- if ((type == 0) || (vlock_mode == VLOCK_MODE_MANUAL_SOFT_ENC))
+ vlock_intput_type = type & VIDTYPE_TYPEMASK;
+ if ((vlock_intput_type == 0) ||
+ (vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC))
return;
- if (type == VIDTYPE_INTERLACE_TOP) {
+ if (vlock_intput_type == VIDTYPE_INTERLACE_TOP) {
if ((source_type == VFRAME_SOURCE_TYPE_TUNER) ||
(source_type == VFRAME_SOURCE_TYPE_CVBS))
/* Input Vsync source select from tv-decoder */
@@ -1192,5 +1311,50 @@ void vdin_vlock_input_sel(unsigned int type,
WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 7, 16, 3);
}
EXPORT_SYMBOL(vdin_vlock_input_sel);
+
+void vlock_param_config(struct device_node *node)
+{
+#ifdef CONFIG_AMLOGIC_LCD
+ unsigned int param[LCD_VLOCK_PARAM_NUM] = {0};
+#endif
+ unsigned int val;
+ int ret;
+
+ ret = of_property_read_u32(node, "vlock_en", &val);
+ if (ret)
+ pr_info("Can't find vlock_en.\n");
+ else
+ vlock_en = val;
+ ret = of_property_read_u32(node, "vlock_mode", &val);
+ if (ret)
+ pr_info("Can't find vlock_mode.\n");
+ else
+ vlock_mode = val;
+ ret = of_property_read_u32(node, "vlock_pll_m_limit", &val);
+ if (ret)
+ pr_info("Can't find vlock_pll_m_limit.\n");
+ else
+ vlock_pll_m_limit = val;
+ ret = of_property_read_u32(node, "vlock_line_limit", &val);
+ if (ret)
+ pr_info("Can't find vlock_line_limit.\n");
+ else
+ vlock_line_limit = val;
+
+#ifdef CONFIG_AMLOGIC_LCD
+ aml_lcd_notifier_call_chain(LCD_EVENT_VLOCK_PARAM, &param);
+ if (param[0]) { /* lcd vlock param is valid */
+ vlock_en = param[1];
+ vlock_mode = param[2];
+ vlock_pll_m_limit = param[3];
+ vlock_line_limit = param[4];
+ }
+#endif
+
+ if (vlock_mode & VLOCK_MODE_MANUAL_MIX_PLL_ENC) {
+ vlock_mode &= ~VLOCK_MODE_MANUAL_MIX_PLL_ENC;
+ vlock_mode |= VLOCK_MODE_MANUAL_PLL;
+ }
+}
/*video lock end*/
diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.h b/drivers/amlogic/media/enhancement/amvecm/vlock.h
index d7bd385..68fa2b2 100644
--- a/drivers/amlogic/media/enhancement/amvecm/vlock.h
+++ b/drivers/amlogic/media/enhancement/amvecm/vlock.h
@@ -18,9 +18,13 @@
#ifndef __AM_VLOCK_H
#define __AM_VLOCK_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_REG_NUM 33
struct vlock_log_s {
@@ -43,6 +47,8 @@ enum vlock_param_e {
VLOCK_MODE,
VLOCK_DIS_CNT_LIMIT,
VLOCK_DELTA_LIMIT,
+ VLOCK_PLL_M_LIMIT,
+ VLOCK_DELTA_CNT_LIMIT,
VLOCK_DEBUG,
VLOCK_DYNAMIC_ADJUST,
VLOCK_STATE,
@@ -70,14 +76,19 @@ extern void vlock_log_print(void);
#define VLOCK_STATE_ENABLE_FORCE_RESET 5
/* video lock */
-#define VLOCK_MODE_AUTO_ENC 0
-#define VLOCK_MODE_AUTO_PLL 1
-#define VLOCK_MODE_MANUAL_PLL 2
-#define VLOCK_MODE_MANUAL_ENC 3
-#define VLOCK_MODE_MANUAL_SOFT_ENC 4
+#define VLOCK_MODE_AUTO_ENC (1 << 0)
+#define VLOCK_MODE_AUTO_PLL (1 << 1)
+#define VLOCK_MODE_MANUAL_PLL (1 << 2)
+#define VLOCK_MODE_MANUAL_ENC (1 << 3)
+#define VLOCK_MODE_MANUAL_SOFT_ENC (1 << 4)
+#define VLOCK_MODE_MANUAL_MIX_PLL_ENC (1 << 5)
#define XTAL_VLOCK_CLOCK 24000000/*vlock use xtal clock*/
+#define VLOCK_PLL_STABLE_CNT 180/*vlock pll stabel cnt limit*/
+#define VLOCK_ENC_STABLE_CNT 180/*vlock enc stabel cnt limit*/
+#define VLOCK_PLL_ADJ_LIMIT 9/*vlock pll adj limit(0x300a default)*/
+
/*vlock_debug mask*/
#define VLOCK_DEBUG_INFO (1 << 0)
#define VLOCK_DEBUG_FLUSH_REG_DIS (1 << 1)
@@ -99,5 +110,6 @@ extern int amvecm_hiu_reg_read(unsigned int reg, unsigned int *val);
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);
#endif
diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c
index de729bb..707dc9b 100644
--- a/drivers/amlogic/media/video_sink/video.c
+++ b/drivers/amlogic/media/video_sink/video.c
@@ -5031,6 +5031,10 @@ static irqreturn_t vsync_isr_in(int irq, void *dev_id)
vsync_count++;
timer_count++;
+#if defined(CONFIG_AMLOGIC_MEDIA_ENHANCEMENT_VECM)
+ vlock_process(vf);/*need call every vsync*/
+#endif
+
switch (READ_VCBUS_REG(VPU_VIU_VENC_MUX_CTRL) & 0x3) {
case 0:
enc_line = (READ_VCBUS_REG(ENCL_INFO_READ) >> 16) & 0x1fff;
@@ -5290,9 +5294,6 @@ 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/lcd/lcd_clk_config.c b/drivers/amlogic/media/vout/lcd/lcd_clk_config.c
index 1b2a57a..530c818 100644
--- a/drivers/amlogic/media/vout/lcd/lcd_clk_config.c
+++ b/drivers/amlogic/media/vout/lcd/lcd_clk_config.c
@@ -1576,6 +1576,7 @@ static void lcd_pll_frac_generate_gxtvbb(struct lcd_config_s *pconf)
static int check_pll_txl(struct lcd_clk_config_s *cConf,
unsigned int pll_fout)
{
+ struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
unsigned int m, n;
unsigned int od1_sel, od2_sel, od3_sel, od1, od2, od3;
unsigned int pll_fod2_in, pll_fod3_in, pll_fvco;
@@ -1612,7 +1613,15 @@ static int check_pll_txl(struct lcd_clk_config_s *cConf,
}
cConf->pll_fvco = pll_fvco;
n = 1;
- od_fb = cConf->od_fb;
+ if (lcd_drv->data->chip_type == LCD_CHIP_TXL) {
+ if (pll_fvco < 3700000)
+ od_fb = 0;
+ else
+ od_fb = 1;
+ cConf->od_fb = od_fb;
+ } else {
+ od_fb = cConf->od_fb;
+ }
pll_fvco = pll_fvco / od_fb_table[od_fb];
m = pll_fvco / cConf->fin;
pll_frac = (pll_fvco % cConf->fin) *
@@ -1789,6 +1798,7 @@ static void lcd_pll_frac_generate_txl(struct lcd_config_s *pconf)
od3 = od_table[cConf->pll_od3_sel];
m = cConf->pll_m;
n = cConf->pll_n;
+ od_fb = cConf->od_fb;
if (lcd_debug_print_flag == 2) {
LCDPR("m=%d, n=%d, od1=%d, od2=%d, od3=%d\n",
@@ -1840,7 +1850,6 @@ static void lcd_pll_frac_generate_txl(struct lcd_config_s *pconf)
LCDPR("%s pll_fvco=%d\n", __func__, pll_fvco);
cConf->pll_fvco = pll_fvco;
- od_fb = cConf->od_fb; /* pll default */
pll_fvco = pll_fvco / od_fb_table[od_fb];
temp = cConf->fin * m / n;
if (pll_fvco >= temp) {
diff --git a/drivers/amlogic/media/vout/lcd/lcd_clk_config.h b/drivers/amlogic/media/vout/lcd/lcd_clk_config.h
index 8724af3..fb0b6bf 100644
--- a/drivers/amlogic/media/vout/lcd/lcd_clk_config.h
+++ b/drivers/amlogic/media/vout/lcd/lcd_clk_config.h
@@ -242,8 +242,8 @@ enum div_sel_e {
#define PLL_OD_SEL_MAX_TXL 3
#define PLL_FREF_MIN_TXL (5 * 1000)
#define PLL_FREF_MAX_TXL (25 * 1000)
-#define PLL_VCO_MIN_TXL (3000 * 1000)
-#define PLL_VCO_MAX_TXL (6000 * 1000)
+#define PLL_VCO_MIN_TXL (2950 * 1000)
+#define PLL_VCO_MAX_TXL (5900 * 1000)
/* video */
#define CLK_DIV_IN_MAX_TXL (3100 * 1000)
diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.c b/drivers/amlogic/media/vout/lcd/lcd_common.c
index 54124b6..3f32095 100644
--- a/drivers/amlogic/media/vout/lcd/lcd_common.c
+++ b/drivers/amlogic/media/vout/lcd/lcd_common.c
@@ -677,6 +677,50 @@ int lcd_power_load_from_unifykey(struct lcd_config_s *pconf,
return 0;
}
+int lcd_vlock_param_load_from_dts(struct lcd_config_s *pconf,
+ struct device_node *child)
+{
+ unsigned int para[4];
+ int ret;
+
+ ret = of_property_read_u32_array(child, "vlock_attr", &para[0], 4);
+ if (ret) {
+ pconf->lcd_control.vlock_param[0] = 0;
+ } else {
+ LCDPR("find vlock_attr\n");
+ pconf->lcd_control.vlock_param[0] = 1; /* vlock_param valid */
+ pconf->lcd_control.vlock_param[1] = para[0];
+ pconf->lcd_control.vlock_param[2] = para[1];
+ pconf->lcd_control.vlock_param[3] = para[2];
+ pconf->lcd_control.vlock_param[4] = para[3];
+ }
+
+ return 0;
+}
+
+int lcd_vlock_param_load_from_unifykey(struct lcd_config_s *pconf,
+ unsigned char *buf)
+{
+ unsigned char *p;
+
+ p = buf;
+
+ pconf->lcd_control.vlock_param[0] = 0;
+ pconf->lcd_control.vlock_param[1] = *(p + LCD_UKEY_VLOCK_VAL_0);
+ pconf->lcd_control.vlock_param[2] = *(p + LCD_UKEY_VLOCK_VAL_1);
+ pconf->lcd_control.vlock_param[3] = *(p + LCD_UKEY_VLOCK_VAL_2);
+ pconf->lcd_control.vlock_param[4] = *(p + LCD_UKEY_VLOCK_VAL_3);
+ if (pconf->lcd_control.vlock_param[1] ||
+ pconf->lcd_control.vlock_param[2] ||
+ pconf->lcd_control.vlock_param[3] ||
+ pconf->lcd_control.vlock_param[4]) {
+ LCDPR("find vlock_attr\n");
+ pconf->lcd_control.vlock_param[0] = 1;
+ }
+
+ return 0;
+}
+
void lcd_optical_vinfo_update(void)
{
struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.h b/drivers/amlogic/media/vout/lcd/lcd_common.h
index 28ba5d9..26a53f9 100644
--- a/drivers/amlogic/media/vout/lcd/lcd_common.h
+++ b/drivers/amlogic/media/vout/lcd/lcd_common.h
@@ -91,6 +91,10 @@ extern int lcd_power_load_from_dts(struct lcd_config_s *pconf,
struct device_node *child);
extern int lcd_power_load_from_unifykey(struct lcd_config_s *pconf,
unsigned char *buf, int key_len, int len);
+extern int lcd_vlock_param_load_from_dts(struct lcd_config_s *pconf,
+ struct device_node *child);
+extern int lcd_vlock_param_load_from_unifykey(struct lcd_config_s *pconf,
+ unsigned char *buf);
extern void lcd_optical_vinfo_update(void);
extern void lcd_timing_init_config(struct lcd_config_s *pconf);
diff --git a/drivers/amlogic/media/vout/lcd/lcd_debug.c b/drivers/amlogic/media/vout/lcd/lcd_debug.c
index 42e008a..85bbdbd 100644
--- a/drivers/amlogic/media/vout/lcd/lcd_debug.c
+++ b/drivers/amlogic/media/vout/lcd/lcd_debug.c
@@ -2249,6 +2249,26 @@ static ssize_t lcd_debug_dither_store(struct class *class,
return count;
}
+static ssize_t lcd_debug_vlock_show(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ struct aml_lcd_drv_s *lcd_drv = aml_lcd_get_driver();
+ ssize_t len = 0;
+
+ len = sprintf(buf, "custome vlock attr:\n"
+ "vlock_valid: %d\n"
+ "vlock_en: %d\n"
+ "vlock_work_mode: %d\n"
+ "vlock_pll_m_limit: %d\n"
+ "vlock_line_limit: %d\n",
+ lcd_drv->lcd_config->lcd_control.vlock_param[0],
+ lcd_drv->lcd_config->lcd_control.vlock_param[1],
+ lcd_drv->lcd_config->lcd_control.vlock_param[2],
+ lcd_drv->lcd_config->lcd_control.vlock_param[3],
+ lcd_drv->lcd_config->lcd_control.vlock_param[4]);
+
+ return len;
+}
#define LCD_DEBUG_DUMP_INFO 0
#define LCD_DEBUG_DUMP_REG 1
@@ -2360,6 +2380,7 @@ static struct class_attribute lcd_debug_class_attrs[] = {
__ATTR(reg, 0200, NULL, lcd_debug_reg_store),
__ATTR(dither, 0644,
lcd_debug_dither_show, lcd_debug_dither_store),
+ __ATTR(vlock, 0644, lcd_debug_vlock_show, NULL),
__ATTR(dump, 0644,
lcd_debug_dump_show, lcd_debug_dump_store),
__ATTR(print, 0644, lcd_debug_print_show, lcd_debug_print_store),
diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c
index 0b54e2d..f6193ac 100644
--- a/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c
+++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/lcd_tablet.c
@@ -883,6 +883,7 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
break;
}
+ lcd_vlock_param_load_from_dts(pconf, child);
ret = lcd_power_load_from_dts(pconf, child);
return ret;
@@ -1139,6 +1140,8 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
}
}
+ lcd_vlock_param_load_from_unifykey(pconf, para);
+
/* step 3: check power sequence */
ret = lcd_power_load_from_unifykey(pconf, para, key_len, len);
if (ret < 0) {
diff --git a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c
index 4b9e40d..b4eb5bc 100644
--- a/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c
+++ b/drivers/amlogic/media/vout/lcd/lcd_tv/lcd_tv.c
@@ -1005,6 +1005,7 @@ static int lcd_config_load_from_dts(struct lcd_config_s *pconf,
break;
}
+ lcd_vlock_param_load_from_dts(pconf, child);
ret = lcd_power_load_from_dts(pconf, child);
return ret;
@@ -1226,6 +1227,8 @@ static int lcd_config_load_from_unifykey(struct lcd_config_s *pconf)
}
}
+ lcd_vlock_param_load_from_unifykey(pconf, para);
+
/* step 3: check power sequence */
ret = lcd_power_load_from_unifykey(pconf, para, key_len, len);
if (ret < 0) {
diff --git a/drivers/amlogic/media/vout/lcd/lcd_vout.c b/drivers/amlogic/media/vout/lcd/lcd_vout.c
index 57436e3..98fb4c0 100644
--- a/drivers/amlogic/media/vout/lcd/lcd_vout.c
+++ b/drivers/amlogic/media/vout/lcd/lcd_vout.c
@@ -158,6 +158,9 @@ static struct lcd_power_ctrl_s lcd_power_config = {
},
};
+/* index 0: valid flag */
+static unsigned int vlock_param[LCD_VLOCK_PARAM_NUM] = {0};
+
static struct lcd_config_s lcd_config_dft = {
.lcd_propname = lcd_propname,
.lcd_basic = {
@@ -189,6 +192,7 @@ static struct lcd_config_s lcd_config_dft = {
.lvds_config = &lcd_lvds_config,
.vbyone_config = &lcd_vbyone_config,
.mipi_config = &lcd_mipi_config,
+ .vlock_param = vlock_param,
},
.lcd_power = &lcd_power_config,
.pinmux_flag = 0xff,
@@ -581,6 +585,26 @@ static struct notifier_block lcd_extern_select_nb = {
.notifier_call = lcd_extern_select_notifier,
};
+static int lcd_vlock_param_notifier(struct notifier_block *nb,
+ unsigned long event, void *data)
+{
+ unsigned int *param;
+
+ if ((event & LCD_EVENT_VLOCK_PARAM) == 0)
+ return NOTIFY_DONE;
+ /* LCDPR("%s: 0x%lx\n", __func__, event); */
+
+ param = (unsigned int *)data;
+ memcpy(param, vlock_param,
+ (LCD_VLOCK_PARAM_NUM * sizeof(unsigned int)));
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block lcd_vlock_param_nb = {
+ .notifier_call = lcd_vlock_param_notifier,
+};
+
static int lcd_notifier_register(void)
{
int ret = 0;
@@ -610,6 +634,9 @@ static int lcd_notifier_register(void)
ret = aml_lcd_notifier_register(&lcd_extern_select_nb);
if (ret)
LCDERR("register lcd_extern_select_nb failed\n");
+ ret = aml_lcd_notifier_register(&lcd_vlock_param_nb);
+ if (ret)
+ LCDERR("register lcd_vlock_param_nb failed\n");
return 0;
}
@@ -625,6 +652,7 @@ static void lcd_notifier_unregister(void)
aml_lcd_notifier_unregister(&lcd_bl_select_nb);
aml_lcd_notifier_unregister(&lcd_extern_select_nb);
+ aml_lcd_notifier_unregister(&lcd_vlock_param_nb);
}
/* **************************************** */
diff --git a/include/linux/amlogic/media/vout/lcd/lcd_notify.h b/include/linux/amlogic/media/vout/lcd/lcd_notify.h
index 00b7f76..2d6e55b 100644
--- a/include/linux/amlogic/media/vout/lcd/lcd_notify.h
+++ b/include/linux/amlogic/media/vout/lcd/lcd_notify.h
@@ -75,6 +75,9 @@
/* lcd bist pattern test occurred */
#define LCD_EVENT_TEST_PATTERN (1 << 14)
+#define LCD_VLOCK_PARAM_NUM 5
+#define LCD_EVENT_VLOCK_PARAM (1 << 16)
+
extern int aml_lcd_notifier_register(struct notifier_block *nb);
extern int aml_lcd_notifier_unregister(struct notifier_block *nb);
diff --git a/include/linux/amlogic/media/vout/lcd/lcd_unifykey.h b/include/linux/amlogic/media/vout/lcd/lcd_unifykey.h
index 5e38698..70e2efb 100644
--- a/include/linux/amlogic/media/vout/lcd/lcd_unifykey.h
+++ b/include/linux/amlogic/media/vout/lcd/lcd_unifykey.h
@@ -90,7 +90,10 @@ struct aml_lcd_unifykey_header_s {
#define LCD_UKEY_V_PERIOD_MAX (LCD_UKEY_MODEL_NAME + 67)
#define LCD_UKEY_PCLK_MIN (LCD_UKEY_MODEL_NAME + 69)
#define LCD_UKEY_PCLK_MAX (LCD_UKEY_MODEL_NAME + 73)
-#define LCD_UKEY_CUST_VAL_8 (LCD_UKEY_MODEL_NAME + 77)
+#define LCD_UKEY_VLOCK_VAL_0 (LCD_UKEY_MODEL_NAME + 77)
+#define LCD_UKEY_VLOCK_VAL_1 (LCD_UKEY_MODEL_NAME + 78)
+#define LCD_UKEY_VLOCK_VAL_2 (LCD_UKEY_MODEL_NAME + 79)
+#define LCD_UKEY_VLOCK_VAL_3 (LCD_UKEY_MODEL_NAME + 80)
#define LCD_UKEY_CUST_VAL_9 (LCD_UKEY_MODEL_NAME + 81)
/* interface (20Byte) */
#define LCD_UKEY_IF_ATTR_0 (LCD_UKEY_MODEL_NAME + 85)/* +36+18+31 byte */
@@ -136,6 +139,7 @@ struct aml_lcd_unifykey_header_s {
#define LCD_UKEY_PHY_ATTR_7 (LCD_UKEY_MODEL_NAME + 156)
#define LCD_UKEY_PHY_ATTR_8 (LCD_UKEY_MODEL_NAME + 157)
#define LCD_UKEY_PHY_ATTR_9 (LCD_UKEY_MODEL_NAME + 158)
+
#define LCD_UKEY_DATA_LEN_V1 (LCD_UKEY_MODEL_NAME + 105)
#define LCD_UKEY_DATA_LEN_V2 (LCD_UKEY_MODEL_NAME + 159)
/* power (5Byte * n) */
diff --git a/include/linux/amlogic/media/vout/lcd/lcd_vout.h b/include/linux/amlogic/media/vout/lcd/lcd_vout.h
index 723957c..0551efe 100644
--- a/include/linux/amlogic/media/vout/lcd/lcd_vout.h
+++ b/include/linux/amlogic/media/vout/lcd/lcd_vout.h
@@ -301,6 +301,7 @@ struct lcd_control_config_s {
struct lvds_config_s *lvds_config;
struct vbyone_config_s *vbyone_config;
struct dsi_config_s *mipi_config;
+ unsigned int *vlock_param;
};
/* **********************************