author | Xiaoliang Wang <xiaoliang.wang@amlogic.com> | 2018-10-18 03:18:16 (GMT) |
---|---|---|
committer | Xiaoliang Wang <xiaoliang.wang@amlogic.com> | 2018-10-18 03:18:16 (GMT) |
commit | 040d86e02d6380f8bced1e9decb5dd6e1e241fed (patch) | |
tree | debca9aa03dec61f849b23db7272a2c670a11537 | |
parent | 5b0a03ce5dcb82aaeaf65925d823a34b173e66b1 (diff) | |
download | common-040d86e02d6380f8bced1e9decb5dd6e1e241fed.zip common-040d86e02d6380f8bced1e9decb5dd6e1e241fed.tar.gz common-040d86e02d6380f8bced1e9decb5dd6e1e241fed.tar.bz2 |
Revert "Revert "vlock: add adj stable check""
This reverts commit 5b0a03ce5dcb82aaeaf65925d823a34b173e66b1.
Change-Id: I5158ce976989fc86211b524ec27ae1d0b09fe93c
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, ¶m); + 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", ¶[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; }; /* ********************************** |