From 315f6d3cda5b9e60cb268ae33c976ef96a2954a6 Mon Sep 17 00:00:00 2001 From: Yong Qin Date: Wed, 19 Dec 2018 14:56:40 +0800 Subject: [PATCH] vlock: vlock for tl1 [1/1] PD#SWPL-3129 Problem: 1.verify manual pll mode 2.modify vlock hiu register access api 3.add a new fsm for tl1 test 4.add chip match data Solution: add function for tl1 Verify: verified on tl1 Change-Id: I75f8d2a40437056135f8dd0fb241016a9ea680df Signed-off-by: Yong Qin --- arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts | 2 +- arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts | 2 +- drivers/amlogic/clk/tl1/tl1.h | 2 + drivers/amlogic/media/enhancement/amvecm/amvecm.c | 73 +- .../media/enhancement/amvecm/arch/vpp_regs.h | 23 +- drivers/amlogic/media/enhancement/amvecm/vlock.c | 745 ++++++++++++++++++--- drivers/amlogic/media/enhancement/amvecm/vlock.h | 42 +- include/linux/amlogic/media/amvecm/amvecm.h | 23 + 8 files changed, 775 insertions(+), 137 deletions(-) diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts index 0a20a90..9b6d1a0 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_skt.dts @@ -460,7 +460,7 @@ }; amlvecm { - compatible = "amlogic, vecm"; + compatible = "amlogic, vecm-tl1"; dev_name = "aml_vecm"; status = "okay"; gamma_en = <1>;/*1:enabel ;0:disable*/ diff --git a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts index ab460d0..dfdb037 100644 --- a/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts +++ b/arch/arm/boot/dts/amlogic/tl1_t962x2_x301.dts @@ -475,7 +475,7 @@ }; amlvecm { - compatible = "amlogic, vecm"; + compatible = "amlogic, vecm-tl1"; dev_name = "aml_vecm"; status = "okay"; gamma_en = <1>;/*1:enabel ;0:disable*/ diff --git a/drivers/amlogic/clk/tl1/tl1.h b/drivers/amlogic/clk/tl1/tl1.h index f8f0377..e678f65 100644 --- a/drivers/amlogic/clk/tl1/tl1.h +++ b/drivers/amlogic/clk/tl1/tl1.h @@ -125,11 +125,13 @@ #define HHI_SYS_PLL_CNTL5 0x308 /* 0xc2 offset in datasheet */ #define HHI_SYS_PLL_CNTL6 0x30c /* 0xc3 offset in datasheet */ +#if 0/*tl1 no*/ #define HHI_HDMI_PLL_CNTL 0x320 /* 0xc8 offset in datasheet */ #define HHI_HDMI_PLL_CNTL2 0x324 /* 0xc9 offset in datasheet */ #define HHI_HDMI_PLL_CNTL3 0x328 /* 0xca offset in datasheet */ #define HHI_HDMI_PLL_CNTL4 0x32C /* 0xcb offset in datasheet */ #define HHI_HDMI_PLL_CNTL5 0x330 /* 0xcc offset in datasheet */ +#endif #define HHI_VID_LOCK_CLK_CNTL 0x3c8 /* 0xf2 offset in datasheet1 */ #define HHI_BT656_CLK_CNTL 0x3d4 /* 0xf5 offset in datasheet1 */ #define HHI_SPICC_CLK_CNTL 0x3dc /* 0xf7 offset in datasheet1 */ diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index 8b8103d..5dc2010 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -31,6 +31,8 @@ #include #include #include +#include +#include /* #include */ #include /* for parse_para_pq */ #include @@ -128,7 +130,7 @@ static struct hdr_metadata_info_s vpp_hdr_metadata_s; static int vdj_mode_flg; struct am_vdj_mode_s vdj_mode_s; -void __iomem *amvecm_hiu_reg_base;/* = *ioremap(0xc883c000, 0x2000); */ +/*void __iomem *amvecm_hiu_reg_base;*//* = *ioremap(0xc883c000, 0x2000); */ static int debug_amvecm; module_param(debug_amvecm, int, 0664); @@ -721,6 +723,7 @@ static ssize_t amvecm_vlock_store(struct class *cla, sel = VLOCK_SUPPORT; } else if (!strncmp(parm[0], "enable", 6)) { vecm_latch_flag |= FLAG_VLOCK_EN; + vlock_set_en(true); } else if (!strncmp(parm[0], "disable", 7)) { vecm_latch_flag |= FLAG_VLOCK_DIS; } else if (!strncmp(parm[0], "status", 6)) { @@ -5988,11 +5991,40 @@ static const struct file_operations amvecm_fops = { #endif .poll = amvecm_poll, }; + +static const struct vecm_match_data_s vecm_dt_xxx = { + .vlk_support = true, + .vlk_new_fsm = 0, + .vlk_hwver = vlock_hw_org, + .vlk_phlock_en = false, +}; + +static const struct vecm_match_data_s vecm_dt_tl1 = { + .vlk_support = true, + .vlk_new_fsm = 1, + .vlk_hwver = vlock_hw_ver2, + .vlk_phlock_en = true, +}; + +static const struct of_device_id aml_vecm_dt_match[] = { + { + .compatible = "amlogic, vecm", + .data = &vecm_dt_xxx, + }, + { + .compatible = "amlogic, vecm-tl1", + .data = &vecm_dt_tl1, + }, + {}, +}; + static void aml_vecm_dt_parse(struct platform_device *pdev) { struct device_node *node; unsigned int val; int ret; + const struct of_device_id *of_id; + struct vecm_match_data_s *matchdata; node = pdev->dev.of_node; /* get integer value */ @@ -6031,6 +6063,18 @@ 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; + + /*get compatible matched device, to get chip related data*/ + of_id = of_match_device(aml_vecm_dt_match, &pdev->dev); + if (of_id != NULL) { + pr_info("%s", of_id->compatible); + matchdata = (struct vecm_match_data_s *)of_id->data; + } else { + matchdata = (struct vecm_match_data_s *)&vecm_dt_xxx; + pr_info("unable to get matched device\n"); + } + vlock_dt_match_init(matchdata); + /*vlock param config*/ vlock_param_config(node); } @@ -6158,16 +6202,7 @@ static int aml_vecm_probe(struct platform_device *pdev) if (is_meson_g12a_cpu() || is_meson_g12b_cpu()) sdr_mode = 2; - /*config vlock mode*/ - /*todo:txlx & g9tv support auto pll,*/ - /*but support not good,need vlsi support optimize*/ - vlock_mode = VLOCK_MODE_MANUAL_PLL; - if (is_meson_gxtvbb_cpu() || - is_meson_txl_cpu() || is_meson_txlx_cpu() - || is_meson_txhd_cpu()) - vlock_en = 1; - else - vlock_en = 0; + vlock_status_init(); hdr_init(&amvecm_dev.hdr_d); aml_vecm_dt_parse(pdev); @@ -6259,13 +6294,6 @@ static void amvecm_shutdown(struct platform_device *pdev) lc_free(); } -static const struct of_device_id aml_vecm_dt_match[] = { - { - .compatible = "amlogic, vecm", - }, - {}, -}; - static struct platform_driver aml_vecm_driver = { .driver = { .name = "aml_vecm", @@ -6284,16 +6312,19 @@ static struct platform_driver aml_vecm_driver = { static int __init aml_vecm_init(void) { - unsigned int hiu_reg_base; + /*unsigned int hiu_reg_base;*/ pr_info("%s:module init\n", __func__); + #if 0 /* remap the hiu bus */ if (is_meson_txlx_cpu() || is_meson_txhd_cpu() || - is_meson_g12a_cpu() || is_meson_g12b_cpu()) + is_meson_g12a_cpu() || is_meson_g12b_cpu() + || is_meson_tl1_cpu()) hiu_reg_base = 0xff63c000; else hiu_reg_base = 0xc883c000; amvecm_hiu_reg_base = ioremap(hiu_reg_base, 0x2000); + #endif if (platform_driver_register(&aml_vecm_driver)) { pr_err("failed to register bl driver module\n"); return -ENODEV; @@ -6305,7 +6336,7 @@ static int __init aml_vecm_init(void) static void __exit aml_vecm_exit(void) { pr_info("%s:module exit\n", __func__); - iounmap(amvecm_hiu_reg_base); + /*iounmap(amvecm_hiu_reg_base);*/ platform_driver_unregister(&aml_vecm_driver); } diff --git a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h index ec7f639..6810134 100644 --- a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h +++ b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h @@ -529,11 +529,19 @@ /*ve dither*/ #define VPP_VE_DITHER_CTRL 0x3120 +/* TL1 */ +/*offset 0x1000*/ +#define HHI_TCON_PLL_CNTL0 0x20 +#define HHI_TCON_PLL_CNTL1 0x21 +#define HHI_HDMI_PLL_VLOCK_CNTL 0xd1 + /* for pll bug */ -#define HHI_HDMI_PLL_CNTL 0x10c8 -#define HHI_HDMI_PLL_CNTL2 0x10c9 -#define HHI_VID_LOCK_CLK_CNTL 0x10f2 -#define HHI_HDMI_PLL_CNTL6 0x10cd + +#define HHI_HDMI_PLL_CNTL 0xc8 +#define HHI_HDMI_PLL_CNTL2 0xc9 +#define HHI_VID_LOCK_CLK_CNTL 0xf2 +#define HHI_HDMI_PLL_CNTL6 0xcd + /* for vlock enc mode adjust begin */ #define ENCL_VIDEO_MAX_LNCNT 0x1cbb #define ENCL_VIDEO_MAX_PXCNT 0x1cb0 @@ -552,13 +560,12 @@ #define ENCT_MAX_LINE_SWITCH_POINT 0x1c88 /* for vlock enc mode adjust end */ -#define HHI_VID_LOCK_CLK_CNTL 0x10f2 - #define VDIN_MEAS_VS_COUNT_LO 0x125c +/*for vlock*/ /*after GXL new add CNTL1,same with CNTL2 on G9TV/GXTVBB*/ -#define HHI_HDMI_PLL_CNTL1 0x10c9 +#define HHI_HDMI_PLL_CNTL1 0xc9 /*after GXL CNTL5[bit3] is same with CNTL6[bit20] on G9TV/GXTVBB*/ -#define HHI_HDMI_PLL_CNTL5 0x10cd +#define HHI_HDMI_PLL_CNTL5 0xcd /* #define VI_HIST_CTRL 0x2e00 */ diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.c b/drivers/amlogic/media/enhancement/amvecm/vlock.c index 8ce8c0c..c1d44c0 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.c +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.c @@ -102,6 +102,12 @@ static unsigned int vlock_log_last_ivcnt; static unsigned int vlock_log_last_ovcnt; static unsigned int vlock_log_delta_m; static unsigned int vlock_log_delta_en; +static unsigned int hhi_pll_reg_m; +static unsigned int hhi_pll_reg_frac; + +static struct stvlock_sig_sts vlock; + +/*static unsigned int hhi_pll_reg_vlock_ctl;*/ module_param(vlock_log_size, uint, 0664); MODULE_PARM_DESC(vlock_log_size, "\n vlock_log_size\n"); module_param(vlock_log_cnt, uint, 0664); @@ -141,13 +147,17 @@ static unsigned int last_i_vsync; int amvecm_hiu_reg_read(unsigned int reg, unsigned int *val) { - *val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2)); + /**val = readl(amvecm_hiu_reg_base+((reg - 0x1000)<<2));*/ + *val = aml_read_hiubus(reg); + /*pr_info("vlock rd hiu reg:0x%x,0x%x\n", (reg - 0x1000), *val);*/ return 0; } int amvecm_hiu_reg_write(unsigned int reg, unsigned int val) { - writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2))); + /*writel(val, (amvecm_hiu_reg_base+((reg - 0x1000)<<2)));*/ + /*pr_info("vlock rd hiu reg:0x%x,0x%x\n", (reg - 0x1000), val);*/ + aml_write_hiubus(reg, val); return 0; } static int amvecm_hiu_reg_write_bits(unsigned int reg, unsigned int value, @@ -224,10 +234,9 @@ static void vlock_enable(bool enable) { unsigned int tmp_value; - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value); - if (is_meson_gxtvbb_cpu()) { if (vlock_mode & VLOCK_MODE_MANUAL_PLL) { + amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value); 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, @@ -246,7 +255,35 @@ static void vlock_enable(bool enable) else amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL5, enable, 3, 1); + } else if (is_meson_tl1_cpu()) { + /*reset*/ + if (vlock_mode & VLOCK_MODE_MANUAL_PLL) { + #if 0 + if (enable == 1) { + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("tl1 vlock enable\n"); + amvecm_hiu_reg_write_bits(hhi_pll_reg_vlock_ctl, + 1, 0, 1); + } else { + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("tl1 vlock disable\n"); + amvecm_hiu_reg_write_bits(hhi_pll_reg_vlock_ctl, + 0, 0, 1); + } + #endif + } else { + /*reset*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + if (!enable) + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0, 1, 2); + } } + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s] (%d)\n", __func__, enable); } static void vlock_hw_reinit(struct vlock_regs_s *vlock_regs, unsigned int len) { @@ -256,14 +293,22 @@ static void vlock_hw_reinit(struct vlock_regs_s *vlock_regs, unsigned int len) return; for (i = 0; i < len; i++) WRITE_VPP_REG(vlock_regs[i].addr, vlock_regs[i].val); + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s]\n", __func__); } static void vlock_setting(struct vframe_s *vf, unsigned int input_hz, unsigned int output_hz) { - unsigned int freq_hz = 0, hiu_reg_value_2_addr = HHI_HDMI_PLL_CNTL2; + unsigned int freq_hz = 0; unsigned int reg_value = 0, hiu_reg_value, hiu_reg_value_2; - unsigned int hiu_m_val, hiu_frac_val, temp_value; + unsigned int hiu_m_val = 0, hiu_frac_val = 0, temp_value; + if (vlock_debug & VLOCK_DEBUG_INFO) { + pr_info(">>>[%s]\n", __func__); + pr_info("inputHz:%d,outputHz:%d\n", input_hz, output_hz); + pr_info("type_original:0x%x\n", vf->type_original); + } amvecm_hiu_reg_write(HHI_VID_LOCK_CLK_CNTL, 0x80); if ((vlock_mode & (VLOCK_MODE_AUTO_ENC | VLOCK_MODE_MANUAL_ENC | @@ -272,6 +317,7 @@ static void vlock_setting(struct vframe_s *vf, vlock_hw_reinit(vlock_enc_setting, VLOCK_DEFAULT_REG_SIZE); /*vlock line limit*/ WRITE_VPP_REG(VPU_VLOCK_OUTPUT0_CAPT_LMT, vlock_capture_limit); + /* VLOCK_CNTL_EN disable */ vlock_enable(0); /* disable to adjust pll */ @@ -292,10 +338,12 @@ static void vlock_setting(struct vframe_s *vf, } /* enable to adjust enc */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 30, 1); - /*clear accum1 value*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); - /*clear accum0 value*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); + if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) { + /*clear accum1 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); + /*clear accum0 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); + } /*@20180314 new add*/ /* *set input & output freq @@ -303,8 +351,14 @@ 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)) - input_hz = input_hz >> 1; + !(vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC)) { + /*tl1 fix i problem*/ + if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) + input_hz = input_hz >> 1; + else + WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, + 1, 28, 1); + } freq_hz = input_hz | (output_hz << 8); WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16); /* @@ -333,8 +387,17 @@ static void vlock_setting(struct vframe_s *vf, *bit0~7:input freq *bit8~15:output freq */ - if (vf->type_original & VIDTYPE_TYPEMASK) - input_hz = input_hz >> 1; + if (vf->type_original & VIDTYPE_TYPEMASK) { + if (get_cpu_type() < MESON_CPU_MAJOR_ID_TL1) + input_hz = input_hz >> 1; + else + WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, + 1, 28, 1); + } else { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) + WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, + 0, 28, 1); + } freq_hz = input_hz | (output_hz << 8); WRITE_VPP_REG_BITS(VPU_VLOCK_MISC_CTRL, freq_hz, 0, 16); /* @@ -349,10 +412,15 @@ static void vlock_setting(struct vframe_s *vf, /*set PLL M_INT;PLL M_frac*/ /* WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, */ /* READ_CBUS_REG_BITS(HHI_HDMI_PLL_CNTL,0,9),12,9); */ - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &hiu_reg_value); - amvecm_hiu_reg_read(hiu_reg_value_2_addr, + amvecm_hiu_reg_read(hhi_pll_reg_m, &hiu_reg_value); + amvecm_hiu_reg_read(hhi_pll_reg_frac, &hiu_reg_value_2); - if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { + hiu_m_val = hiu_reg_value & 0xff; + /*discard low 5 bits*/ + hiu_frac_val = (hiu_reg_value_2 >> 5) & 0xfff; + reg_value = (hiu_m_val << 12) + hiu_frac_val; + } else if (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) { hiu_m_val = hiu_reg_value & 0x1FF; hiu_frac_val = hiu_reg_value_2 & 0x3FF; if (hiu_reg_value_2 & 0x800) { @@ -366,6 +434,12 @@ static void vlock_setting(struct vframe_s *vf, } reg_value = (hiu_m_val << 12) + (hiu_frac_val << 2); + } else { + pr_info("err: m f value\n"); + } + if (vlock_debug & VLOCK_DEBUG_INFO) { + pr_info("hiu_m_val=0x%x\n", hiu_m_val); + pr_info("hiu_frac_val=0x%x\n", hiu_frac_val); } WRITE_VPP_REG_BITS(VPU_VLOCK_MX4096, reg_value, 0, 21); /*vlock_pll_adj_limit = (reg_value * 0x8000) >> 24;*/ @@ -404,29 +478,33 @@ static void vlock_setting(struct vframe_s *vf, else if (vf->source_type == VFRAME_SOURCE_TYPE_HDMI) /* Input Vsync source select from hdmi-rx */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 16, 3); + + /*enable vlock*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 31, 1); } void vlock_vmode_check(void) { const struct vinfo_s *vinfo; - unsigned int t0, t1, hiu_reg_addr; + unsigned int t0, t1; if (vlock_en == 0) return; - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - hiu_reg_addr = HHI_HDMI_PLL_CNTL1; - else - hiu_reg_addr = HHI_HDMI_PLL_CNTL2; + vinfo = get_current_vinfo(); vlock_vmode_changed = 0; if ((vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE) || (pre_hiu_reg_m == 0)) { 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); - pre_hiu_reg_frac = t0 & 0xfff; - pre_hiu_reg_m = t1 & 0x1ff; + amvecm_hiu_reg_read(hhi_pll_reg_frac, &t0); + amvecm_hiu_reg_read(hhi_pll_reg_m, &t1); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { + pre_hiu_reg_frac = (t0 >> 5) & 0xfff; + pre_hiu_reg_m = t1 & 0xff; + } else { + pre_hiu_reg_frac = t0 & 0xfff; + pre_hiu_reg_m = t1 & 0x1ff; + } } if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | VLOCK_MODE_AUTO_ENC | @@ -479,7 +557,6 @@ void vlock_vmode_check(void) static void vlock_disable_step1(void) { unsigned int m_reg_value, tmp_value, enc_max_line, enc_max_pixel; - unsigned int hiu_reg_addr; /* VLOCK_CNTL_EN disable */ vlock_enable(0); @@ -487,24 +564,41 @@ static void vlock_disable_step1(void) 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) { - tmp_value = (tmp_value & 0xfffff000) | - (pre_hiu_reg_frac & 0xfff); - amvecm_hiu_reg_write(hiu_reg_addr, tmp_value); - } - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value); - m_reg_value = tmp_value & 0x1ff; - if ((m_reg_value != pre_hiu_reg_m) && - (pre_hiu_reg_m != 0)) { - tmp_value = (tmp_value & 0xfffffe00) | - (pre_hiu_reg_m & 0x1ff); - amvecm_hiu_reg_write(HHI_HDMI_PLL_CNTL, tmp_value); + if (cpu_after_eq(MESON_CPU_MAJOR_ID_TL1)) { + amvecm_hiu_reg_read(hhi_pll_reg_frac, + &tmp_value); + m_reg_value = (tmp_value >> 5) & 0xfff; + if (m_reg_value != pre_hiu_reg_frac) { + tmp_value = (tmp_value & 0xfffff000) | + (pre_hiu_reg_frac & 0xfff); + amvecm_hiu_reg_write(hhi_pll_reg_frac, + tmp_value); + } + amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value); + m_reg_value = tmp_value & 0xff; + if ((m_reg_value != pre_hiu_reg_m) && + (pre_hiu_reg_m != 0)) { + tmp_value = (tmp_value & 0xffffff00) | + (pre_hiu_reg_m & 0xff); + amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value); + } + } else { + amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value); + m_reg_value = tmp_value & 0xfff; + if (m_reg_value != pre_hiu_reg_frac) { + tmp_value = (tmp_value & 0xfffff000) | + (pre_hiu_reg_frac & 0xfff); + amvecm_hiu_reg_write(hhi_pll_reg_frac, + tmp_value); + } + amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value); + m_reg_value = tmp_value & 0x1ff; + if ((m_reg_value != pre_hiu_reg_m) && + (pre_hiu_reg_m != 0)) { + tmp_value = (tmp_value & 0xfffffe00) | + (pre_hiu_reg_m & 0x1ff); + amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value); + } } } if ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | @@ -537,11 +631,14 @@ static void vlock_disable_step1(void) } vlock_pll_stable_cnt = 0; vlock_enc_stable_flag = 0; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } static void vlock_disable_step2(void) { unsigned int temp_val; + /* need delay to disable follow regs(vlsi suggest!!!) */ if (vlock_dis_cnt > 0) vlock_dis_cnt--; @@ -556,10 +653,16 @@ static void vlock_disable_step2(void) /* disable vid_lock_en */ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 31, 1); vlock_state = VLOCK_STATE_DISABLE_STEP2_DONE; - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val); - if (is_meson_gxtvbb_cpu() && (((temp_val >> 21) & 0x3) != 0)) - amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, 0, 21, 2); + if (is_meson_gxtvbb_cpu()) { + amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &temp_val); + if (((temp_val >> 21) & 0x3) != 0) + amvecm_hiu_reg_write_bits(HHI_HDMI_PLL_CNTL6, + 0, 21, 2); + } } + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo, unsigned int input_hz, unsigned int output_hz) @@ -584,10 +687,13 @@ static void vlock_enable_step1(struct vframe_s *vf, struct vinfo_s *vinfo, vlock_sync_limit_flag = 0; vlock_vmode_changed = 0; vlock_dis_cnt = 0; - vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE; + /*vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE;*/ vlock_pll_stable_cnt = 0; vlock_log_cnt = 0; vlock_enc_stable_flag = 0; + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } void vlock_log_start(void) @@ -715,6 +821,8 @@ static void vlock_enable_step3_enc(void) vlock_reg_get(); vlock_log_cnt++; } + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } static void vlock_enable_step3_soft_enc(void) @@ -840,7 +948,10 @@ static void vlock_enable_step3_soft_enc(void) vlock_reg_get(); vlock_log_cnt++; } + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info(">>>[%s]\n", __func__); } + /*check pll adj value (0x3020),otherwise may cause blink*/ static void vlock_pll_adj_limit_check(unsigned int *pll_val) { @@ -863,16 +974,12 @@ static void vlock_pll_adj_limit_check(unsigned int *pll_val) } } } + static void vlock_enable_step3_pll(void) { - unsigned int m_reg_value, tmp_value, abs_val, hiu_reg_addr; + unsigned int m_reg_value, tmp_value, abs_val; unsigned int ia, oa, abs_cnt; - if (get_cpu_type() >= MESON_CPU_MAJOR_ID_GXL) - hiu_reg_addr = HHI_HDMI_PLL_CNTL1; - else - hiu_reg_addr = HHI_HDMI_PLL_CNTL2; - /*vs_i*/ tmp_value = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); abs_val = abs(vlock_log_last_ivcnt - tmp_value); @@ -913,18 +1020,26 @@ static void vlock_enable_step3_pll(void) return; } /*check adjust delta limit*/ - vlock_pll_adj_limit_check(&m_reg_value); + if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) + 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 */ - 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) + if (is_meson_gxtvbb_cpu()) { + amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL6, &tmp_value); + if (((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 + *0:progressive type + *1:interlace type + */ + if (vlock_intput_type && + (vlock.dtdata->vlk_hwver < vlock_hw_ver2)) ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST) / 2; else ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); @@ -936,45 +1051,69 @@ static void vlock_enable_step3_pll(void) return; } /*frac*/ - amvecm_hiu_reg_read(hiu_reg_addr, &tmp_value); - abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff)); - if ((abs_val >= vlock_log_delta_frac) && (vlock_log_delta_en&(1<<3))) - pr_info("vlock frac delta:%d(0x%x,0x%x)\n", - abs_val, ((m_reg_value & 0xfff) >> 2), + amvecm_hiu_reg_read(hhi_pll_reg_frac, &tmp_value); + if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) { + abs_val = abs(((m_reg_value & 0xfff) >> 2) - (tmp_value & 0xfff)); - 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); + if ((abs_val >= vlock_log_delta_frac) && + (vlock_log_delta_en&(1<<3))) + 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) && + (abs_cnt > vlock_delta_cnt_limit)) { + tmp_value = (tmp_value & 0xfffff000) | + ((m_reg_value & 0xfff) >> 2); + amvecm_hiu_reg_write(hhi_pll_reg_frac, 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)) && + (abs_cnt < vlock_enc_adj_limit)) + vlock_pll_stable_cnt++; + else + vlock_pll_stable_cnt = 0; + } else { + tmp_value = (tmp_value & 0xfff80000) | + ((m_reg_value & 0xfff) << 5); + amvecm_hiu_reg_write(hhi_pll_reg_frac, tmp_value); } - /*check stable by diff frac*/ - if ((abs_val < (2 * vlock_delta_limit)) && - (abs_cnt < vlock_enc_adj_limit)) - vlock_pll_stable_cnt++; - else - vlock_pll_stable_cnt = 0; + /*m*/ - amvecm_hiu_reg_read(HHI_HDMI_PLL_CNTL, &tmp_value); - abs_val = abs(((m_reg_value >> 16) & 0x1ff) - (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 ((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); + amvecm_hiu_reg_read(hhi_pll_reg_m, &tmp_value); + if (vlock.dtdata->vlk_hwver < vlock_hw_ver2) { + abs_val = abs(((m_reg_value >> 16) & 0xff) - + (pre_hiu_reg_m & 0xff)); + 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 ((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_pll_reg_m, tmp_value); + vlock_pll_val_last &= 0x0000ffff; + vlock_pll_val_last |= (m_reg_value & 0xffff0000); + } + } else { + tmp_value = (tmp_value & 0xffffff00) | + ((m_reg_value >> 16) & 0xff); + amvecm_hiu_reg_write(hhi_pll_reg_m, tmp_value); } + /*check stable by diff m*/ - if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) - vlock_pll_stable_cnt = 0; + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + if (((m_reg_value >> 16) & 0xff) != (tmp_value & 0xff)) + vlock_pll_stable_cnt = 0; + } else { + if (((m_reg_value >> 16) & 0x1ff) != (tmp_value & 0x1ff)) + vlock_pll_stable_cnt = 0; + } } /* won't change this function internal seqence, * if really need change,please be carefull and check with vlsi @@ -998,6 +1137,7 @@ void amve_vlock_process(struct vframe_s *vf) vlock_dis_cnt_no_vf = 0; if (vecm_latch_flag & FLAG_VLOCK_EN) { vlock_enable_step1(vf, vinfo, input_hz, output_hz); + vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE; vlock_en = 1; vecm_latch_flag &= ~FLAG_VLOCK_EN; } @@ -1035,43 +1175,66 @@ void amve_vlock_process(struct vframe_s *vf) (input_hz != pre_input_freq) || (output_hz != pre_output_freq) || vlock_vmode_changed || - (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET)) + (vlock_state == VLOCK_STATE_ENABLE_FORCE_RESET)) { vlock_enable_step1(vf, vinfo, input_hz, output_hz); + vlock_state = VLOCK_STATE_ENABLE_STEP1_DONE; + } if ((vlock_sync_limit_flag < 10) && (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_MANUAL_PLL)))) { + /*reset*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); + /*clear first 3 frame internal cnt*/ WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0); WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("amve_vlock_process-0\n"); } if ((vlock_sync_limit_flag == 4) && ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | VLOCK_MODE_MANUAL_PLL)))) { + /*release reset*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("amve_vlock_process-1\n"); } } + if ((vlock_sync_limit_flag == 5) && (vlock_state == VLOCK_STATE_ENABLE_STEP1_DONE)) { /*input_vs_cnt =*/ /*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/ /* 0, 28);*/ input_vs_cnt = XTAL_VLOCK_CLOCK/input_hz; - if (vf->type_original & VIDTYPE_TYPEMASK) + /*tl1 not need */ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1) && + vf->type_original & VIDTYPE_TYPEMASK) input_vs_cnt = input_vs_cnt << 1; + WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MAX, input_vs_cnt*125/100); WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MIN, input_vs_cnt*70/100); + /*cal accum1 value*/ WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); /*cal accum0 value*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + //WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); vlock_state = VLOCK_STATE_ENABLE_STEP2_DONE; + + /*tl1 auto pll,swich clk need after several frames*/ + if (is_meson_tl1_cpu() && + (vlock_mode & VLOCK_MODE_AUTO_PLL)) + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0x3, 1, 2); + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("amve_vlock_process-2\n"); } else if (vlock_dynamic_adjust && (vlock_sync_limit_flag > 5) && (vlock_state == VLOCK_STATE_ENABLE_STEP2_DONE) && @@ -1149,18 +1312,370 @@ void amve_vlock_resume(void) } } +void vlock_clear_frame_counter(void) +{ + vlock.frame_cnt_in = 0; + vlock.frame_cnt_no = 0; +} + +void vlock_set_en(bool en) +{ + /*if (vlock.dtdata->vlk_support)*/ + vlock_en = en; +} + +void vlock_status_init(void) +{ + /*config vlock mode*/ + /*todo:txlx & g9tv support auto pll,*/ + /*but support not good,need vlsi support optimize*/ + vlock_mode = VLOCK_MODE_MANUAL_PLL; + if (is_meson_gxtvbb_cpu() || + is_meson_txl_cpu() || is_meson_txlx_cpu() + || is_meson_tl1_cpu()) + vlock_en = 1; + else + vlock_en = 0; + + if (is_meson_tl1_cpu()) { + hhi_pll_reg_m = HHI_TCON_PLL_CNTL0; + hhi_pll_reg_frac = HHI_TCON_PLL_CNTL1; + /*hhi_pll_reg_vlock_ctl = HHI_HDMI_PLL_VLOCK_CNTL;*/ + } else if (get_cpu_type() >= + MESON_CPU_MAJOR_ID_GXL) { + hhi_pll_reg_m = HHI_HDMI_PLL_CNTL; + hhi_pll_reg_frac = HHI_HDMI_PLL_CNTL2; + } else { + hhi_pll_reg_m = HHI_HDMI_PLL_CNTL; + hhi_pll_reg_frac = HHI_HDMI_PLL_CNTL2; + } + + vlock.fsm_sts = VLOCK_STATE_NULL; + vlock.fsm_prests = VLOCK_STATE_NULL; + vlock.vf_sts = false; + vlock.vmd_chg = false; + vlock.md_support = false; + vlock_clear_frame_counter(); + pr_info("%s vlock_en:%d\n", __func__, vlock_en); +} + +void vlock_dt_match_init(struct vecm_match_data_s *pdata) +{ + vlock.dtdata = pdata; + /*vlock_en = vlock.dtdata.vlk_support;*/ + pr_info("vlock dt support: %d\n", vlock.dtdata->vlk_support); + pr_info("vlock dt new_fsm: %d\n", vlock.dtdata->vlk_new_fsm); + pr_info("vlock dt hwver: %d\n", vlock.dtdata->vlk_hwver); + pr_info("vlock dt phlock_en: %d\n", vlock.dtdata->vlk_phlock_en); +} + +#if 1 + +u32 vlock_fsm_check_support(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 ret = true; + + if (((pvlock->input_hz != pvlock->output_hz) && (vlock_adapt == 0)) || + (pvlock->input_hz == 0) || (pvlock->output_hz == 0) || + (((vf->type_original & VIDTYPE_TYPEMASK) + != VIDTYPE_PROGRESSIVE) && + is_meson_txlx_package_962E())) { + + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s] for no support case!!!\n", + __func__); + ret = false; + } + + if (vlock_vmode_change_status == VOUT_EVENT_MODE_CHANGE_PRE) { + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s] for vmode change pre case!!!\n", + __func__); + ret = false; + } + + return ret; +} + +u32 vlock_fsm_input_check(struct stvlock_sig_sts *vlock, struct vframe_s *vf) +{ + u32 ret = 0; + u32 vframe_sts; + struct vinfo_s *vinfo = NULL; + + if (vf == NULL) + vframe_sts = false; + else + vframe_sts = true; + + if (vf != NULL) { + vinfo = get_current_vinfo(); + vlock->input_hz = vlock_check_input_hz(vf); + vlock->output_hz = vlock_check_output_hz( + vinfo->sync_duration_num); + } + + /*check vf exist status*/ + if (vlock->vf_sts != vframe_sts) { + vlock->vf_sts = vframe_sts; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("vlock vfsts chg %d\n", vframe_sts); + ret = 1; + } else if (vlock_vmode_change_status) { + /*check video mode status*/ + vlock->vmd_chg = true; + ret = 1; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("vlock vmode chg\n"); + } + + if (vlock->vf_sts) + vlock->md_support = vlock_fsm_check_support(vlock, vf); + + return ret; +} + +u32 vlock_fsm_to_en_func(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 ret = 0; + struct vinfo_s *vinfo; + + if ((vf->source_type != pre_source_type) || + (vf->source_mode != pre_source_mode) || + (pvlock->input_hz != pre_input_freq) || + (pvlock->output_hz != pre_output_freq) || + vlock_vmode_changed || + (pvlock->fsm_sts == + VLOCK_STATE_ENABLE_FORCE_RESET)) { + vinfo = get_current_vinfo(); + vlock_enable_step1(vf, vinfo, + pvlock->input_hz, pvlock->output_hz); + ret = 1; + } + + return ret; +} + +u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 ret = 0; + u32 input_vs_cnt; + + if ((pvlock->frame_cnt_in <= 3) && + ((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); + /*clear first 3 frame internal cnt*/ + WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0); + WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("%s -0\n", __func__); + } else if ((pvlock->frame_cnt_in == 4) && + ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | + VLOCK_MODE_MANUAL_PLL)))) { + /*cal accum0 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + /*cal accum1 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("%s -1\n", __func__); + } else if (pvlock->frame_cnt_in == 5) { + /*input_vs_cnt =*/ + /*READ_VPP_REG_BITS(VPU_VLOCK_RO_VS_I_DIST,*/ + /* 0, 28);*/ + input_vs_cnt = XTAL_VLOCK_CLOCK/pvlock->input_hz; + /*tl1 not need */ + if (!cpu_after_eq(MESON_CPU_MAJOR_ID_TL1) && + vf->type_original & VIDTYPE_TYPEMASK) + input_vs_cnt = input_vs_cnt << 1; + + WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MAX, + input_vs_cnt*125/100); + WRITE_VPP_REG(VPU_VLOCK_LOOP1_IMISSYNC_MIN, + input_vs_cnt*70/100); + + /*cal accum1 value*/ + WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); + /*cal accum0 value*/ + //WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + + /* + * tl1 auto pll,swich clk need after + *several frames + */ + if (is_meson_tl1_cpu() && + IS_AUTO_PLL_MODE(vlock_mode)) + amvecm_hiu_reg_write_bits( + HHI_HDMI_PLL_VLOCK_CNTL, 0x3, 1, 2); + + ret = 1; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("%s -2\n", __func__); + } + + return ret; +} + +u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 ret = 0; + + if (vlock_dynamic_adjust && + (cpu_after_eq(MESON_CPU_MAJOR_ID_GXTVBB)) && + (IS_MANUAL_MODE(vlock_mode))) { + if (IS_MANUAL_ENC_MODE(vlock_mode)) + vlock_enable_step3_enc(); + else if (IS_MANUAL_PLL_MODE(vlock_mode)) + vlock_enable_step3_pll(); + else if (IS_MANUAL_SOFTENC_MODE(vlock_mode)) + vlock_enable_step3_soft_enc(); + /*check stable*/ + /*....*/ + } + + return ret; +} + + +void vlock_fsm_monitor(struct vframe_s *vf) +{ + u32 changed; + + changed = vlock_fsm_input_check(&vlock, vf); + vlock_vmode_check(); + switch (vlock.fsm_sts) { + case VLOCK_STATE_NULL: + if (vlock.vf_sts) { + /*have frame in*/ + if (vlock.frame_cnt_in++ == 3) { + /*vframe input valid*/ + if (vlock.md_support) { + if (vlock_fsm_to_en_func(&vlock, vf)) { + vlock_clear_frame_counter(); + vlock.fsm_sts = + VLOCK_STATE_ENABLE_STEP1_DONE; + } else { + /*error waitting here*/ + vlock_clear_frame_counter(); + } + } + } + } else if (vlock.vmd_chg) { + vlock_clear_frame_counter(); + vlock.vmd_chg = false; + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP2_DONE; + } else { + /*disabled and waitting here*/ + vlock_clear_frame_counter(); + } + break; + + case VLOCK_STATE_ENABLE_STEP1_DONE: + if (vlock.vf_sts) { + vlock.frame_cnt_in++; + if (vlock_fsm_en_step1_func(&vlock, vf)) + vlock.fsm_sts = VLOCK_STATE_ENABLE_STEP2_DONE; + } else if (vlock.vmd_chg) { + vlock_clear_frame_counter(); + vlock.vmd_chg = false; + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } else { + vlock.frame_cnt_in = 0; + if (vlock.frame_cnt_no++ > vlock_dis_cnt_no_vf_limit) { + /*go to disable state*/ + vlock_clear_frame_counter(); + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } + } + break; + + case VLOCK_STATE_ENABLE_STEP2_DONE: + if (vlock.vf_sts) { + if (!vlock.md_support) { + /*function not support*/ + vlock_clear_frame_counter(); + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } else if (vecm_latch_flag & FLAG_VLOCK_DIS) { + /*disable vlock by vecm cmd*/ + vlock_disable_step1(); + vlock_disable_step2(); + vlock_en = 0; + vecm_latch_flag &= ~FLAG_VLOCK_DIS; + if (vlock_debug & VLOCK_DEBUG_INFO) + pr_info("[%s] vlock dis\n", __func__); + vlock_clear_frame_counter(); + vlock.fsm_sts = VLOCK_STATE_NULL; + } else { + /*normal mode*/ + vlock.frame_cnt_no = 0; + vlock_fsm_en_step2_func(&vlock, vf); + } + } else if (vlock.vmd_chg) { + vlock_clear_frame_counter(); + vlock.vmd_chg = false; + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } else { + /*no frame input*/ + if (vlock.frame_cnt_no++ > vlock_dis_cnt_no_vf_limit) { + /*go to disable state*/ + vlock_clear_frame_counter(); + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP1_DONE; + } else { + vlock_fsm_en_step2_func(&vlock, vf); + } + } + break; + + case VLOCK_STATE_DISABLE_STEP1_DONE: + vlock_disable_step1(); + vlock.fsm_sts = VLOCK_STATE_DISABLE_STEP2_DONE; + break; + + case VLOCK_STATE_DISABLE_STEP2_DONE: + vlock_disable_step2(); + vlock.fsm_sts = VLOCK_STATE_NULL; + break; + + default: + pr_info("err state %d\n", vlock.fsm_sts); + break; + } + + /*capture log*/ + 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(); + vlock_log_cnt++; + } + + if ((vlock_debug & VLOCK_DEBUG_INFO) && + vlock.fsm_sts != vlock.fsm_prests) { + pr_info(">>> %s fsm %d to %d\n", __func__, + vlock.fsm_prests, vlock.fsm_sts); + vlock.fsm_prests = vlock.fsm_sts; + } +} +#endif + /*new packed separeted from amvecm_on_vs,avoid the influencec of repeate call, *which may affect vlock process */ void vlock_process(struct vframe_s *vf) { - if (probe_ok == 0) + if (probe_ok == 0 || !vlock_en) return; /* todo:vlock processs only for tv chip */ - if (is_meson_gxtvbb_cpu() || - is_meson_txl_cpu() || is_meson_txlx_cpu() - || is_meson_txhd_cpu()) { + if (vlock.dtdata->vlk_new_fsm) + vlock_fsm_monitor(vf); + else { if (vf != NULL) amve_vlock_process(vf); else @@ -1227,6 +1742,7 @@ void vlock_status(void) 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); + pr_info("vecm_latch_flag:0x%x\n", vecm_latch_flag); pr_info("vlock_sync_limit_flag:%d\n", vlock_sync_limit_flag); pr_info("pre_hiu_reg_m:0x%x\n", pre_hiu_reg_m); pr_info("pre_hiu_reg_frac:0x%x\n", pre_hiu_reg_frac); @@ -1248,17 +1764,28 @@ void vlock_status(void) 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("vlk_new_fsm:%d\n", vlock.dtdata->vlk_new_fsm); pr_info("vlock driver version : %s\n", VLOCK_VER); } void vlock_reg_dump(void) { unsigned int addr; + unsigned int val; pr_info("----dump vlock reg----\n"); for (addr = (0x3000); addr <= (0x3020); addr++) pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", (0xd0100000+(addr<<2)), addr, READ_VPP_REG(addr)); + + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) { + for (addr = (0x3021); addr <= (0x302a); addr++) + pr_info("[0x%x]vcbus[0x%04x]=0x%08x\n", + (0xd0100000+(addr<<2)), addr, + READ_VPP_REG(addr)); + amvecm_hiu_reg_read(HHI_HDMI_PLL_VLOCK_CNTL, &val); + pr_info("HIU [0x%04x]=0x%08x\n", HHI_HDMI_PLL_VLOCK_CNTL, val); + } } /*work around method for vlock process hdmirx input interlace source.@20170803 **for interlace input,TOP and BOT have one line delta, @@ -1270,8 +1797,17 @@ void vlock_reg_dump(void) void vdin_vlock_input_sel(unsigned int type, enum vframe_source_type_e source_type) { + if (vlock.dtdata->vlk_hwver >= vlock_hw_ver2) + return; + /* + *1:fromhdmi rx , + *2:from tv-decoder, + *3:from dvin, + *4:from dvin, + *5:from 2nd bt656 + */ vlock_intput_type = type & VIDTYPE_TYPEMASK; - if ((vlock_intput_type == 0) || + if ((vlock_intput_type == VIDTYPE_PROGRESSIVE) || (vlock_mode & VLOCK_MODE_MANUAL_SOFT_ENC)) return; if (vlock_intput_type == VIDTYPE_INTERLACE_TOP) { @@ -1351,6 +1887,7 @@ void vlock_param_config(struct device_node *node) vlock_mode &= ~VLOCK_MODE_MANUAL_MIX_PLL_ENC; vlock_mode |= VLOCK_MODE_MANUAL_PLL; } + pr_info("param_config vlock_en:%d\n", vlock_en); } int vlock_notify_callback(struct notifier_block *block, unsigned long cmd, diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.h b/drivers/amlogic/media/enhancement/amvecm/vlock.h index 96784fb..fee85c5 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.h +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.h @@ -23,7 +23,7 @@ #include #include "linux/amlogic/media/amvecm/ve.h" -#define VLOCK_VER "Ref.2018/11/07a" +#define VLOCK_VER "Ref.2018/12/24" #define VLOCK_REG_NUM 33 @@ -59,6 +59,18 @@ enum vlock_param_e { VLOCK_PARAM_MAX, }; +struct stvlock_sig_sts { + u32 fsm_sts; + u32 fsm_prests; + u32 vf_sts; + u32 vmd_chg; + u32 frame_cnt_in; + u32 frame_cnt_no; + u32 input_hz; + u32 output_hz; + bool md_support; + struct vecm_match_data_s *dtdata; +}; extern void amve_vlock_process(struct vframe_s *vf); extern void amve_vlock_resume(void); extern void vlock_param_set(unsigned int val, enum vlock_param_e sel); @@ -84,6 +96,29 @@ extern void vlock_log_print(void); #define VLOCK_MODE_MANUAL_SOFT_ENC (1 << 4) #define VLOCK_MODE_MANUAL_MIX_PLL_ENC (1 << 5) + +#define IS_MANUAL_MODE(md) (md & \ + (VLOCK_MODE_MANUAL_PLL | \ + VLOCK_MODE_MANUAL_ENC | \ + VLOCK_MODE_MANUAL_SOFT_ENC)) + +#define IS_PLL_MODE(md) (md & \ + (VLOCK_MODE_MANUAL_PLL | \ + VLOCK_MODE_AUTO_PLL)) + +#define IS_AUTO_PLL_MODE(md) (md & \ + VLOCK_MODE_AUTO_PLL) + +#define IS_MANUAL_ENC_MODE(md) (md & \ + VLOCK_MODE_MANUAL_ENC) + +#define IS_MANUAL_PLL_MODE(md) (md & \ + VLOCK_MODE_MANUAL_PLL) + +#define IS_MANUAL_SOFTENC_MODE(md) (md & \ + VLOCK_MODE_MANUAL_SOFT_ENC) + + #define XTAL_VLOCK_CLOCK 24000000/*vlock use xtal clock*/ #define VLOCK_SUPPORT_HDMI (1 << 0) @@ -106,7 +141,7 @@ extern void vlock_log_print(void); extern unsigned int vlock_mode; extern unsigned int vlock_en; extern unsigned int vecm_latch_flag; -extern void __iomem *amvecm_hiu_reg_base; +/*extern void __iomem *amvecm_hiu_reg_base;*/ extern unsigned int probe_ok; extern void lcd_ss_enable(bool flag); @@ -123,4 +158,7 @@ extern void vlock_lcd_param_work(struct work_struct *p_work); extern int vlock_notify_callback(struct notifier_block *block, unsigned long cmd, void *para); #endif +extern void vlock_status_init(void); +extern void vlock_dt_match_init(struct vecm_match_data_s *pdata); +extern void vlock_set_en(bool en); diff --git a/include/linux/amlogic/media/amvecm/amvecm.h b/include/linux/amlogic/media/amvecm/amvecm.h index ec6cd64..eeeb64d 100644 --- a/include/linux/amlogic/media/amvecm/amvecm.h +++ b/include/linux/amlogic/media/amvecm/amvecm.h @@ -300,6 +300,29 @@ enum ve_pq_timing_e { TIMING_MAX, }; +enum vlock_hw_ver_e { + /*gxtvbb*/ + vlock_hw_org, + /* + *txl + *txlx + */ + vlock_hw_ver1, + /* tl1 later + * fix bug:i problem + * fix bug:affect ss function + * add: phase lock + */ + vlock_hw_ver2, +}; + +struct vecm_match_data_s { + u32 vlk_support; + u32 vlk_new_fsm; + enum vlock_hw_ver_e vlk_hwver; + u32 vlk_phlock_en; +}; + /*overscan: *length 0~31bit :number of crop; *src_timing: bit31: on: load/save all crop -- 2.7.4