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);
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,
{
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,
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)
{
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 |
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 */
}
/* 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
*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);
/*
*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);
/*
/*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) {
}
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;*/
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 |
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);
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 |
}
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--;
/* 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)
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)
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)
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)
{
}
}
}
+
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);
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);
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
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;
}
(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) &&
}
}
+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
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);
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,
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) {
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,