From c73ef5f4303dcfb89f2bc0be6741c1f92780c242 Mon Sep 17 00:00:00 2001 From: Yong Qin Date: Mon, 8 Apr 2019 14:24:11 +0800 Subject: [PATCH] vlock: add phase lock pll mode [1/1] PD#SWPL-6899 Problem: enable vlock phase lock function in pll mode Solution: 1.when phase lock on, and when phase lock flag not assert disable ss. 2.after phase lock flag assert, restore ss Verify: tl1 Change-Id: I2f9f6ec76468b1043c1b7ec99b2daa4f9d69ae60 Signed-off-by: Yong Qin Conflicts: drivers/amlogic/media/enhancement/amvecm/vlock.c --- .../amlogic/media/enhancement/amvecm/amvecm.c | 2 +- .../enhancement/amvecm/amvecm_vlock_regmap.h | 3 +- .../media/enhancement/amvecm/arch/vpp_regs.h | 4 +- .../amlogic/media/enhancement/amvecm/vlock.c | 135 ++++++++++++++---- .../amlogic/media/enhancement/amvecm/vlock.h | 2 +- .../amlogic/media/vout/lcd/lcd_clk_config.c | 27 ++++ 6 files changed, 139 insertions(+), 34 deletions(-) diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm.c b/drivers/amlogic/media/enhancement/amvecm/amvecm.c index 430ea828330e..e92a2320bfcc 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm.c +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm.c @@ -6545,7 +6545,7 @@ 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 = false, + .vlk_phlock_en = true, }; static const struct of_device_id aml_vecm_dt_match[] = { diff --git a/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h b/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h index 862b4faad881..45e74bfaa81b 100644 --- a/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h +++ b/drivers/amlogic/media/enhancement/amvecm/amvecm_vlock_regmap.h @@ -75,12 +75,11 @@ static struct vlock_regs_s vlock_pll_setting[VLOCK_DEFAULT_REG_SIZE] = { #define VLOCK_PHASE_REG_SIZE 9 static struct vlock_regs_s vlock_pll_phase_setting[VLOCK_PHASE_REG_SIZE] = { - {0x3004, 0x00620680}, + {0x3004, 0x00604680}, {0x3009, 0x06000000}, {0x300a, 0x00600000}, {0x300b, 0x06000000}, {0x300c, 0x00600000}, - {0x3025, 0x00002000}, {0x3027, 0x00022002}, {0x3028, 0x00001000}, diff --git a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h index 48f1be555193..0f8e1bc534a9 100644 --- a/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h +++ b/drivers/amlogic/media/enhancement/amvecm/arch/vpp_regs.h @@ -331,7 +331,7 @@ #define VPU_VLOCK_RO_LINE_PIX_ADJ 0x3013 #define VPU_VLOCK_RO_OUTPUT_00_01 0x3014 #define VPU_VLOCK_RO_OUTPUT_10_11 0x3015 -#define VPU_VLOCK_MX4096 0x3016 +#define VPU_VLOCK_MX4096 0x3016 #define VPU_VLOCK_STBDET_WIN0_WIN1 0x3017 #define VPU_VLOCK_STBDET_CLP 0x3018 #define VPU_VLOCK_STBDET_ABS_WIN0 0x3019 @@ -339,7 +339,7 @@ #define VPU_VLOCK_STBDET_SGN_WIN0 0x301b #define VPU_VLOCK_STBDET_SGN_WIN1 0x301c #define VPU_VLOCK_ADJ_EN_SYNC_CTRL 0x301d -#define VPU_VLOCK_GCLK_EN 0x301e +#define VPU_VLOCK_GCLK_EN 0x301e #define VPU_VLOCK_LOOP1_ACCUM_LMT 0x301f #define VPU_VLOCK_RO_M_INT_FRAC 0x3020 #define VPU_VLOCK_RO_PH_DIS 0x3021 diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.c b/drivers/amlogic/media/enhancement/amvecm/vlock.c index f9405f1b6c07..4f589a0f2f59 100644 --- a/drivers/amlogic/media/enhancement/amvecm/vlock.c +++ b/drivers/amlogic/media/enhancement/amvecm/vlock.c @@ -212,6 +212,14 @@ void vlock_set_panel_pll(u32 m, u32 frac) vlock_set_panel_pll_frac(frac); } +void vlock_set_panel_ss(u32 onoff) +{ + if (onoff) + lcd_ss_enable(1); + else + lcd_ss_enable(0); +} + /*returen 1: use phase lock*/ int phase_lock_check(void) { @@ -775,6 +783,10 @@ static bool vlock_disable_step2(void) pr_info(">>>[%s]\n", __func__); } + /*restore ss setting*/ + if (!vlock.ss_sts) + vlock_set_panel_ss(true); + return ret; } @@ -1595,7 +1607,6 @@ void vlock_status_init(void) /* vlock.phlock_percent = phlock_percent; */ vlock_clear_frame_counter(); - pr_info("%s vlock_en:%d\n", __func__, vlock_en); } @@ -1636,7 +1647,7 @@ void vlock_set_phase_en(u32 en) if (en) vlock.phlock_en = true; else - vlock.dtdata->vlk_phlock_en = false; + vlock.phlock_en = false; pr_info("vlock phlock_en=%d\n", en); } @@ -1645,22 +1656,18 @@ void vlock_phaselock_check(struct stvlock_sig_sts *pvlock, { /*vs_i*/ u32 ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); - u32 val; - static u32 cnt = 48; + u32 val, pre; - if (vlock.dtdata->vlk_phlock_en) { - if (cnt++ > 50) { + if (vlock.phlock_en) { + if ((pvlock->frame_cnt_in%100) == 0) { ia = READ_VPP_REG(VPU_VLOCK_RO_VS_I_DIST); + pre = READ_VPP_REG(VPU_VLOCK_LOOP1_PHSDIF_TGT); val = (ia * (100 + vlock.phlock_percent))/200; - WRITE_VPP_REG(VPU_VLOCK_LOOP1_PHSDIF_TGT, val); - cnt = 0; - #if 0 - /*reset*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1); - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1); - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); - #endif + if (val != pre) { + WRITE_VPP_REG(VPU_VLOCK_LOOP1_PHSDIF_TGT, val); + vlock_reset(1); + vlock_reset(0); + } } } } @@ -1670,10 +1677,10 @@ bool vlock_get_phlock_flag(void) u32 flag; u32 sts; - if (!vlock.dtdata->vlk_phlock_en) - return false; + if (!vlock.phlock_en) + return false; - flag = READ_VPP_REG(VPU_VLOCK_RO_LCK_FRM) >> 17; + flag = READ_VPP_REG(VPU_VLOCK_RO_LCK_FRM) >> 16; flag = flag&0x01; if (vlock.dtdata->vlk_new_fsm) @@ -1692,7 +1699,7 @@ bool vlock_get_vlock_flag(void) u32 flag; u32 sts; - flag = READ_VPP_REG(VPU_VLOCK_RO_LCK_FRM) >> 16; + flag = READ_VPP_REG(VPU_VLOCK_RO_LCK_FRM) >> 17; flag = flag&0x01; if (vlock.dtdata->vlk_new_fsm) @@ -1825,6 +1832,11 @@ u32 vlock_fsm_to_en_func(struct stvlock_sig_sts *pvlock, vinfo = get_current_vinfo(); vlock_enable_step1(vf, vinfo, pvlock->input_hz, pvlock->output_hz); + if (IS_PLL_MODE(vlock_mode) && + pvlock->phlock_en) { + vlock_set_panel_ss(false); + pvlock->ss_sts = false; + } ret = 1; } @@ -1840,8 +1852,9 @@ u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock, 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); + /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 5, 1);*/ + /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 1, 2, 1);*/ + vlock_reset(1); /*clear first 3 frame internal cnt*/ WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM0, 0); WRITE_VPP_REG(VPU_VLOCK_OVWRITE_ACCUM1, 0); @@ -1851,9 +1864,10 @@ u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock, ((vlock_mode & (VLOCK_MODE_MANUAL_ENC | VLOCK_MODE_MANUAL_PLL)))) { /*cal accum0 value*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1); + /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 5, 1);*/ /*cal accum1 value*/ - WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1); + /*WRITE_VPP_REG_BITS(VPU_VLOCK_CTRL, 0, 2, 1);*/ + vlock_reset(0); if (vlock_debug & VLOCK_DEBUG_INFO) pr_info("%s -1\n", __func__); } else if (pvlock->frame_cnt_in == 5) { @@ -1870,12 +1884,11 @@ u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock, 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); + /*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_reset(0); /* * tl1 auto pll,swich clk need after *several frames @@ -1897,6 +1910,68 @@ u32 vlock_fsm_en_step1_func(struct stvlock_sig_sts *pvlock, return ret; } +void vlock_fsm_check_lock_sts(struct stvlock_sig_sts *pvlock, + struct vframe_s *vf) +{ + u32 frqlock_sts = vlock_get_vlock_flag(); + u32 phlock_sts = vlock_get_phlock_flag(); + u32 pherr; + static u32 rstflag; + + /*check frq lock*/ + if (pvlock->frqlock_sts != frqlock_sts) { + pr_info("frq lock sts(%d,%d) cnt:%d\n", pvlock->frqlock_sts, + frqlock_sts, pvlock->frame_cnt_in); + pvlock->frqlock_sts = frqlock_sts; + } + + /*check phase error*/ + if (IS_PLL_MODE(vlock_mode) && + pvlock->phlock_en) { + /*after frq lock, then enable phase lock*/ + /*check phase err*/ + pherr = READ_VPP_REG(VPU_VLOCK_RO_PH_ERR) & 0xffffff; + if (pherr & 0x800000) + pherr = 0xffffff - pherr + 1;/*negative value*/ + + if (rstflag) { + rstflag = false; + vlock_reset(0); + } else if (pherr > 0x1ff) { + if ((pvlock->frame_cnt_in%80) == 0) { + vlock_reset(1); + rstflag = true; + } + } + } + + /*check phase lock*/ + if (pvlock->phlock_en && + (pvlock->phlock_sts != phlock_sts)) { + pr_info("ph lock sts(%d,%d) cnt:%d\n", pvlock->phlock_sts, + phlock_sts, pvlock->frame_cnt_in); + pvlock->phlock_sts = phlock_sts; + if (phlock_sts && !pvlock->ss_sts && + (pvlock->frame_cnt_in > 25)) { + vlock_set_panel_ss(true); + pvlock->ss_sts = true; + } + } + + /*pretect and enable ss*/ + if (IS_PLL_MODE(vlock_mode) && + pvlock->phlock_en) { + /*error check*/ + if ((pvlock->frame_cnt_in >= 3500) && (!pvlock->ss_sts)) { + pr_info("vlock warning: set back ss on(%d, %d)\n", + frqlock_sts, phlock_sts); + pvlock->pll_mode_pause = true; + pvlock->ss_sts = true; + vlock_set_panel_ss(true); + } + } +} + u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock, struct vframe_s *vf) { @@ -1907,7 +1982,8 @@ u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock, (IS_MANUAL_MODE(vlock_mode))) { if (IS_MANUAL_ENC_MODE(vlock_mode)) vlock_enable_step3_enc(); - else if (IS_MANUAL_PLL_MODE(vlock_mode)) + else if (IS_MANUAL_PLL_MODE(vlock_mode) && + (!pvlock->pll_mode_pause)) vlock_enable_step3_pll(); else if (IS_MANUAL_SOFTENC_MODE(vlock_mode)) vlock_enable_step3_soft_enc(); @@ -1918,6 +1994,9 @@ u32 vlock_fsm_en_step2_func(struct stvlock_sig_sts *pvlock, /*check phase*/ vlock_phaselock_check(pvlock, vf); + + vlock_fsm_check_lock_sts(pvlock, vf); + return ret; } diff --git a/drivers/amlogic/media/enhancement/amvecm/vlock.h b/drivers/amlogic/media/enhancement/amvecm/vlock.h index a1008a3bfca7..628f72a80700 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.2019/4/02a" +#define VLOCK_VER "Ref.2019/4/10a finetune phase lock" #define VLOCK_REG_NUM 33 diff --git a/drivers/amlogic/media/vout/lcd/lcd_clk_config.c b/drivers/amlogic/media/vout/lcd/lcd_clk_config.c index 8f143badc2bf..295059c010ec 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_clk_config.c +++ b/drivers/amlogic/media/vout/lcd/lcd_clk_config.c @@ -2228,6 +2228,33 @@ lcd_set_spread_spectrum_end: LCDPR("%s\n", __func__); } +/* design for vlock, don't save ss_level to clk_config */ +int lcd_ss_enable(unsigned int flag) +{ + unsigned int level; + unsigned long flags = 0; + int ret = -1; + + spin_lock_irqsave(&lcd_clk_lock, flags); + + if (clk_conf.data == NULL) { + LCDERR("%s: clk config data is null\n", __func__); + goto lcd_ss_enable_end; + } + + if (clk_conf.data->set_ss_level) { + level = flag ? clk_conf.ss_level : 0; + clk_conf.data->set_ss_level(level); + } + +lcd_ss_enable_end: + spin_unlock_irqrestore(&lcd_clk_lock, flags); + + if (lcd_debug_print_flag) + LCDPR("%s\n", __func__); + return ret; +} + int lcd_encl_clk_msr(void) { unsigned int clk_mux;