From 1e203c8df43b15848bedb65db69df6d198ebd477 Mon Sep 17 00:00:00 2001 From: "qiang.liu" Date: Fri, 15 Dec 2023 20:54:57 +0800 Subject: [PATCH] tvafe: add wss and snow use tvafe pattern [1/1] PD#SWPL-147997 Problem: 1.wss function not ok 2.snow display not good Solution: 1.add wss function 2.optimize snow display Verify: t5m Change-Id: Ie384b65525fc238fc5d44f7ac15c65703a8734b3 Signed-off-by: qiang.liu --- drivers/media/vin/tvin/tvafe/tvafe.c | 101 +++++++-- drivers/media/vin/tvin/tvafe/tvafe.h | 4 + drivers/media/vin/tvin/tvafe/tvafe_cvd.c | 95 ++++++-- drivers/media/vin/tvin/tvafe/tvafe_cvd.h | 4 +- drivers/media/vin/tvin/tvafe/tvafe_debug.c | 3 +- drivers/media/vin/tvin/tvafe/tvafe_regs.h | 8 + drivers/media/vin/tvin/tvafe/tvafe_vbi.c | 244 ++++++++++++++++----- drivers/media/vin/tvin/tvafe/tvafe_vbi.h | 14 +- drivers/media/vin/tvin/tvin_frontend.h | 1 + drivers/media/vin/tvin/tvin_global.h | 1 + drivers/media/vin/tvin/vdin/vdin_ctl.c | 4 + drivers/media/vin/tvin/vdin/vdin_drv.c | 9 +- drivers/media/vin/tvin/vdin/vdin_drv.h | 1 + drivers/media/vin/tvin/vdin/vdin_sm.c | 4 +- 14 files changed, 386 insertions(+), 107 deletions(-) diff --git a/drivers/media/vin/tvin/tvafe/tvafe.c b/drivers/media/vin/tvin/tvafe/tvafe.c index ee23f5ce0..8f35136dd 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe.c +++ b/drivers/media/vin/tvin/tvafe/tvafe.c @@ -40,6 +40,7 @@ /* Local include */ #include +#include #include "../tvin_frontend.h" #include "../tvin_global.h" #include "../tvin_format_table.h" @@ -64,7 +65,8 @@ static dev_t tvafe_devno; static struct class *tvafe_clsp; #define TVAFE_TIMER_INTERVAL (HZ / 100) /* 10ms, #define HZ 100 */ -#define TVAFE_RATIO_CNT 30 +#define TVAFE_RATIO_CNT 22 +#define TVAFE_RATIO_EFFECT_CNT 19 static struct am_regs_s tvafe_regs; static struct tvafe_pin_mux_s tvafe_pinmux; @@ -516,6 +518,8 @@ static int tvafe_dec_open(struct tvin_frontend_s *fe, enum tvin_port_e port, #ifdef CONFIG_AMLOGIC_MEDIA_TVIN_VBI tvafe_vbi_set_wss(); #endif + tvafe->aspect_ratio_cnt = 0; + tvafe->aspect_ratio = TVIN_ASPECT_NULL; tvafe_pr_info("%s open port:0x%x ok.\n", __func__, port); mutex_unlock(&devp->afe_mutex); @@ -733,19 +737,30 @@ static void tvafe_dec_close(struct tvin_frontend_s *fe, enum tvin_port_type_e po mutex_unlock(&devp->afe_mutex); } +/* return value: + * true: get aspect ratio or not need get + * false: not get aspect ratio + */ static void tvafe_get_aspect_ratio_value(struct tvafe_dev_s *devp) { int i; + bool has_interference_value = false; struct tvafe_info_s *tvafe = &devp->tvafe; - enum tvin_aspect_ratio_e aspect_ratio = TVIN_ASPECT_NULL; + enum tvin_aspect_ratio_e maybe_ratio = TVIN_ASPECT_NULL; + enum tvin_aspect_ratio_e aspect_ratio = tvafe->aspect_ratio; static int count[10] = {0}; - if (!(devp->tvafe_function_sel & TVAFE_WSS_FUNCTION)) { - aspect_ratio = TVIN_ASPECT_NULL; + if (!(devp->tvafe_function_sel & TVAFE_WSS_FUNCTION)) return; - } - if (tvafe->cvd2.info.state != TVAFE_CVD2_STATE_FIND) + if (tvafe->cvd2.info.state != TVAFE_CVD2_STATE_FIND || + tvafe->cvd2.hw.no_sig || + (!devp->tvafe.cvd2.hw.acc4xx_cnt && + !devp->tvafe.cvd2.hw.acc3xx_cnt)) + return; + + if (tvafe->cvd2.config_fmt != TVIN_SIG_FMT_CVBS_PAL_I && + tvafe->cvd2.config_fmt != TVIN_SIG_FMT_CVBS_SECAM) return; aspect_ratio = tvafe_cvd2_get_wss(); @@ -780,19 +795,37 @@ static void tvafe_get_aspect_ratio_value(struct tvafe_dev_s *devp) case TVIN_ASPECT_MAX: break; } - /*over 22/30 times,ratio is effective*/ - if (++tvafe->aspect_ratio_cnt > TVAFE_RATIO_CNT) { - for (i = 0; i < TVIN_ASPECT_MAX; i++) { - if (count[i] > (TVAFE_RATIO_CNT - 8)) { - if (tvafe->aspect_ratio != i) - pr_info("wss aspect_ratio:%d->%d,%d\n", - tvafe->aspect_ratio, i, aspect_ratio); - tvafe->aspect_ratio = i; - break; + /* over 6/22 times,ratio is effective*/ + if (++tvafe->aspect_ratio_cnt > devp->tvafe_ratio_cnt) { + //has wss value judge, maybe is interference value + for (i = 1; i < TVIN_ASPECT_MAX; i++) { + if (count[i] > (devp->tvafe_ratio_cnt - devp->tvafe_ratio_effect_cnt) && + !maybe_ratio) { + maybe_ratio = i; + count[0] = 0; + } else if (count[i] > 2) { + has_interference_value = true; + count[0] = 0; } } - for (i = 0; i < TVIN_ASPECT_MAX; i++) + if (maybe_ratio && !has_interference_value) {//not interference confirm wss value + if (tvafe->aspect_ratio != maybe_ratio) + pr_info("wss aspect_ratio:%d->%d,%d\n", + tvafe->aspect_ratio, maybe_ratio, aspect_ratio); + tvafe->aspect_ratio = maybe_ratio; + } + for (i = 1; i < TVIN_ASPECT_MAX; i++) count[i] = 0; + //not wss value judge + if (count[0] >= (devp->tvafe_ratio_cnt * 2 - 1)) { + if (tvafe->aspect_ratio != 0 && tvafe_dbg_print & TVAFE_DBG_WSS) + pr_info("wss aspect_ratio:%d->0,%d\n", + tvafe->aspect_ratio, aspect_ratio); + //tvafe->aspect_ratio = 0; + count[0] = 0; + } else if (count[0] > devp->tvafe_ratio_cnt + 1) { + count[0] = 0; + } tvafe->aspect_ratio_cnt = 0; } } @@ -868,8 +901,7 @@ static int tvafe_dec_isr(struct tvin_frontend_s *fe, unsigned int hcnt64, } } - if (tvafe->cvd2.info.isr_cnt++ >= 65536) - tvafe->cvd2.info.isr_cnt = 0; + tvafe->cvd2.info.isr_cnt++; /* TVAFE CVD2 3D works abnormally => reset cvd2 */ tvafe_cvd2_check_3d_comb(&tvafe->cvd2); @@ -889,7 +921,11 @@ static int tvafe_dec_isr(struct tvin_frontend_s *fe, unsigned int hcnt64, tvafe_cvd2_adj_hs_ntsc(&tvafe->cvd2, hcnt64); } } - tvafe_get_aspect_ratio_value(devp); + /* prevent zoom aspect ratio change */ + if ((devp->tvafe_function_sel & TVAFE_WSS_FUNCTION) && + !tvafe->aspect_ratio && + tvafe->cvd2.info.isr_cnt < (devp->tvafe_ratio_cnt >> 1)) + return TVIN_BUF_SKIP; return TVIN_BUF_NULL; } @@ -948,6 +984,7 @@ static bool tvafe_is_nosig(struct tvin_frontend_s *fe, enum tvin_port_type_e por struct tvafe_info_s *tvafe = &devp->tvafe; enum tvin_port_e port = tvafe->parm.port; enum tvafe_adc_ch_e adc_ch = TVAFE_ADC_CH_NULL; + unsigned int snow_value; if (!(devp->flags & TVAFE_FLAG_DEV_OPENED) || (devp->flags & TVAFE_POWERDOWN_IN_IDLE)) { @@ -965,8 +1002,7 @@ static bool tvafe_is_nosig(struct tvin_frontend_s *fe, enum tvin_port_type_e por if (white_pattern_reset_pag(port, &tvafe->cvd2)) return true; - if (tvafe->cvd2.info.smr_cnt++ >= 65536) - tvafe->cvd2.info.smr_cnt = 0; + tvafe->cvd2.smr_cnt++; if (devp->flags & TVAFE_FLAG_DEV_STARTED) ret = tvafe_cvd2_no_sig(&tvafe->cvd2, &devp->mem, 1); @@ -975,6 +1011,8 @@ static bool tvafe_is_nosig(struct tvin_frontend_s *fe, enum tvin_port_type_e por if (!tvafe_mode && IS_TVAFE_ATV_SRC(port) && (devp->flags & TVAFE_FLAG_DEV_SNOW_FLAG)) { /* playing snow */ + get_random_bytes(&snow_value, sizeof(snow_value)); + W_APB_REG(ACD_REG_A6, snow_value); tvafe->cvd2.info.snow_state[3] = tvafe->cvd2.info.snow_state[2]; tvafe->cvd2.info.snow_state[2] = tvafe->cvd2.info.snow_state[1]; tvafe->cvd2.info.snow_state[1] = tvafe->cvd2.info.snow_state[0]; @@ -1005,8 +1043,7 @@ static bool tvafe_is_nosig(struct tvin_frontend_s *fe, enum tvin_port_type_e por adc_ch = tvafe_port_to_channel(port, devp->pinmux); tvafe_adc_pin_mux(adc_ch); } - if (!(devp->flags & TVAFE_FLAG_DEV_STARTED)) - tvafe_get_aspect_ratio_value(devp); + tvafe_get_aspect_ratio_value(devp); return ret; } @@ -1240,6 +1277,19 @@ static bool tvafe_cvbs_get_secam_phase(struct tvin_frontend_s *fe) return 0; } +/* + * clear tvafe value when snow stop + */ +static void tvafe_clear_value(struct tvin_frontend_s *fe) +{ + struct tvafe_dev_s *devp = container_of(fe, struct tvafe_dev_s, + frontend); + struct tvafe_info_s *tvafe = &devp->tvafe; + + tvafe->aspect_ratio_cnt = 0; + tvafe->aspect_ratio = TVIN_ASPECT_NULL; +} + bool tvafe_get_snow_cfg(void) { return snow_cfg; @@ -1286,6 +1336,7 @@ static struct tvin_state_machine_ops_s tvafe_sm_ops = { .vga_get_param = NULL, .check_frame_skip = tvafe_cvbs_check_frame_skip, .get_secam_phase = tvafe_cvbs_get_secam_phase, + .frontend_clr_value = tvafe_clear_value, }; static int tvafe_open(struct inode *inode, struct file *file) @@ -1392,6 +1443,8 @@ static long tvafe_ioctl(struct file *file, tvafe_pr_info("TVIN_IOC_S_AFE_SNOW_ON\n"); break; case TVIN_IOC_S_AFE_SNOW_OFF: + if (devp->flags & TVAFE_FLAG_DEV_SNOW_FLAG) + devp->tvafe.cvd2.info.isr_cnt = 0; tvafe_snow_config(0); tvafe_snow_config_clamp(0); devp->flags &= (~TVAFE_FLAG_DEV_SNOW_FLAG); @@ -2040,6 +2093,8 @@ static int tvafe_drv_probe(struct platform_device *pdev) force_stable = false; tvafe_atv_search_channel = false; tvafe_manual_fmt_save = TVIN_SIG_FMT_NULL; + tdevp->tvafe_ratio_cnt = TVAFE_RATIO_CNT; + tdevp->tvafe_ratio_effect_cnt = TVAFE_RATIO_EFFECT_CNT; tvafe_pr_info("driver probe ok\n"); diff --git a/drivers/media/vin/tvin/tvafe/tvafe.h b/drivers/media/vin/tvin/tvafe/tvafe.h index 428019a3e..d178cf731 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe.h +++ b/drivers/media/vin/tvin/tvafe/tvafe.h @@ -79,6 +79,8 @@ struct tvafe_info_s { #define TVAFE_AUTO_HS_MODE BIT(6) #define TVAFE_AUTO_VS_MODE BIT(7) +#define TVAFE_WSS_FUNCTION BIT(0) + struct tvafe_user_param_s { unsigned int cutwindow_val_h[5]; unsigned int cutwindow_val_v[5]; @@ -152,6 +154,8 @@ struct tvafe_dev_s { unsigned int frame_skip_enable; unsigned int sizeof_tvafe_dev_s; unsigned int tvafe_function_sel; + unsigned int tvafe_ratio_cnt; + unsigned int tvafe_ratio_effect_cnt; }; bool tvafe_get_snow_cfg(void); diff --git a/drivers/media/vin/tvin/tvafe/tvafe_cvd.c b/drivers/media/vin/tvin/tvafe/tvafe_cvd.c index bef427010..99184f51a 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_cvd.c +++ b/drivers/media/vin/tvin/tvafe/tvafe_cvd.c @@ -239,7 +239,9 @@ void cvd_vbi_mem_set(unsigned int offset, unsigned int size) void cvd_vbi_config(void) { /* 20190719: teletext slicer mode 1 to avoid error data */ - W_APB_BIT(CVD2_VBI_SLIER_MODE_SEL, 1, 2, 2); + W_APB_BIT(CVD2_VBI_SLIER_MODE_SEL, 1, TT_SLICER_MODE_BIT, TT_SLICER_MODE_WID); + W_APB_BIT(CVD2_VBI_SLIER_MODE_SEL, 1, WSS_SLICER_MODE_BIT, WSS_SLICER_MODE_WID); + W_APB_BIT(CVD2_VBI_DATA_STATUS, 0x1, WSS_RD_DONE, WSS_RD_DONE_WID); W_APB_REG(CVD2_VBI_CC_START, VBI_START_CC); W_APB_REG(CVD2_VBI_WSS_START, 0x54); W_VBI_APB_REG(CVD2_VBI_TT_START, VBI_START_TT); @@ -346,6 +348,7 @@ static void tvafe_cvd2_write_mode_reg(struct tvafe_cvd2_s *cvd2, struct tvafe_user_param_s *user_param = tvafe_get_user_param(); unsigned int i = 0; unsigned int vbi_ctl_val; + struct tvafe_dev_s *devp = tvafe_get_dev(); vbi_ctl_val = R_APB_REG(CVD2_VBI_FRAME_CODE_CTL); /*disable vbi*/ @@ -391,7 +394,10 @@ static void tvafe_cvd2_write_mode_reg(struct tvafe_cvd2_s *cvd2, (tvafe_cpu_type() == TVAFE_CPU_TYPE_TL1 || tvafe_cpu_type() >= TVAFE_CPU_TYPE_TM2)) { W_APB_BIT(CVD2_OUTPUT_CONTROL, 3, 5, 2); - W_APB_REG(ACD_REG_6C, 0x80500000); + if (devp->flags & TVAFE_FLAG_DEV_SNOW_FLAG) + W_APB_REG(ACD_REG_6C, 0x90300000); + else + W_APB_REG(ACD_REG_6C, 0x80500000); } /* load CVD2 reg 0x70~ff (char) */ @@ -468,10 +474,11 @@ static void tvafe_cvd2_write_mode_reg(struct tvafe_cvd2_s *cvd2, /* TVAFE_CVD2_WSS_ENABLE */ /* config data type */ - /*line17 for PAL M*/ - W_APB_REG(CVD2_VBI_DATA_TYPE_LINE17, 0xcc); - /*line23 for PAL B,D,G,H,I,N,CN*/ - W_APB_REG(CVD2_VBI_DATA_TYPE_LINE23, 0xcc); + /*line17 for PAL M; line23 for PAL B,D,G,H,I,N,CN */ + //W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE17, vbi_data_type); + if (cvd2->config_fmt == TVIN_SIG_FMT_CVBS_PAL_I || + cvd2->config_fmt == TVIN_SIG_FMT_CVBS_SECAM) + W_APB_REG(CVD2_VBI_DATA_TYPE_LINE23, 0x0c); /* config wss dto */ W_APB_REG(CVD2_VBI_WSS_DTO_MSB, 0x20); W_APB_REG(CVD2_VBI_WSS_DTO_LSB, 0x66); @@ -488,6 +495,9 @@ static void tvafe_cvd2_write_mode_reg(struct tvafe_cvd2_s *cvd2, W_APB_REG(ACD_REG_22, 0x04080000); W_APB_REG(CVD2_VBI_FRAME_CODE_CTL, vbi_ctl_val); + if (cvd2->config_fmt == TVIN_SIG_FMT_CVBS_PAL_I || + cvd2->config_fmt == TVIN_SIG_FMT_CVBS_SECAM) + W_APB_BIT(CVD2_VBI_FRAME_CODE_CTL, 1, VBI_EN_BIT, VBI_EN_WID); /* for tuner picture quality */ if (cvd2->pq_conf) { @@ -861,18 +871,34 @@ inline void tvafe_cvd2_try_format(struct tvafe_cvd2_s *cvd2, } } -// check tvafe status whether need drop frame -static void tvafe_check_skip_frame(struct tvafe_cvd2_s *cvd2) +/* check tvafe signal whether is no signal + * return value: + * true: signal no signal + * false: signal has signal + */ +static bool tvafe_check_no_signal(struct tvafe_cvd2_s *cvd2) { struct tvafe_user_param_s *user_param = tvafe_get_user_param(); if (cvd2->info.state != TVAFE_CVD2_STATE_FIND) - return; + return false; if (!cvd2->hw.acc4xx_cnt && !cvd2->hw.acc3xx_cnt && !R_APB_REG(CVD2_STATUS_REGISTER2) && cvd2->info.h_unlock_cnt > user_param->unlock_cnt_max && cvd2->info.v_unlock_cnt > user_param->unlock_cnt_max) + return true; + else + return false; +} + +// check tvafe status whether need drop frame +static void tvafe_check_skip_frame(struct tvafe_cvd2_s *cvd2) +{ + if (cvd2->info.state != TVAFE_CVD2_STATE_FIND) + return; + + if (tvafe_check_no_signal(cvd2)) tvin_notify_vdin_skip_frame(1, 0); } @@ -1336,7 +1362,7 @@ static void tvafe_cvd2_non_std_signal_det(struct tvafe_cvd2_s *cvd2) chroma_sum_filt, cvd2->hw.h_nonstd, cvd2->hw.v_nonstd); tvafe_pr_info("%s: smr_cnt=%d, nonstd_cnt=%d, stable_cnt=%d, nonstd_flag=%d, dgain=0x%x, non_std_enable=%d\n", - __func__, cvd2->info.smr_cnt, + __func__, cvd2->smr_cnt, cvd2->info.nonstd_cnt, cvd2->info.nonstd_stable_cnt, cvd2->info.nonstd_flag, dgain, @@ -1359,7 +1385,7 @@ static void tvafe_cvd2_non_std_signal_det(struct tvafe_cvd2_s *cvd2) cvd2->hw.h_nonstd, cvd2->hw.v_nonstd); tvafe_pr_info("%s: smr_cnt=%d, nonstd_cnt=%d, stable_cnt=%d, nonstd_flag=%d, dgain=0x%x, non_std_enable=%d\n", - __func__, cvd2->info.smr_cnt, + __func__, cvd2->smr_cnt, cvd2->info.nonstd_cnt, cvd2->info.nonstd_stable_cnt, cvd2->info.nonstd_flag, dgain, @@ -3105,7 +3131,13 @@ void tvafe_snow_config(unsigned int on_off) (tvafe_cpu_type() == TVAFE_CPU_TYPE_TL1 || tvafe_cpu_type() >= TVAFE_CPU_TYPE_TM2)) { W_APB_BIT(CVD2_OUTPUT_CONTROL, 3, 5, 2); - W_APB_REG(ACD_REG_6C, 0x80500000); + if (on_off) { + W_APB_REG(ACD_REG_6C, 0x90300000); + W_APB_REG(ACD_REG_A6, 0x123456); + } else { + W_APB_REG(ACD_REG_6C, 0x80500000); + W_APB_REG(ACD_REG_A6, 0x2); + } } if (tvafe_snow_function_flag == 0 || @@ -3176,7 +3208,10 @@ enum tvin_aspect_ratio_e tvafe_cvd2_get_wss(void) unsigned int full_format = 0; enum tvin_aspect_ratio_e aspect_ratio = TVIN_ASPECT_NULL; - full_format = R_APB_BIT(CVD2_VBI_WSS_DATA1, WSSDATA1_BYTE1_BIT, WSSDATA1_BYTE1_WID); + if (R_APB_BIT(CVD2_VBI_DATA_STATUS, WSS_RDY, WSS_RDY_WID)) + full_format = R_APB_BIT(CVD2_VBI_WSS_DATA1, WSSDATA1_BYTE1_BIT, WSSDATA1_BYTE1_WID); + else + full_format = TVIN_AR_NOT_VALUE; //not valid wss data if (full_format == TVIN_AR_14x9_LB_CENTER_VAL) aspect_ratio = TVIN_ASPECT_14x9_LB_CENTER; @@ -3198,8 +3233,9 @@ enum tvin_aspect_ratio_e tvafe_cvd2_get_wss(void) aspect_ratio = TVIN_ASPECT_NULL; if (tvafe_dbg_print & TVAFE_DBG_WSS) - tvafe_pr_info("%s full_format:%#x aspect_ratio:%#x\n", - __func__, full_format, aspect_ratio); + tvafe_pr_info("%s full_format:%#x aspect_ratio:%#x data:%#x,%#x,%#x\n", + __func__, full_format, aspect_ratio, R_APB_REG(CVD2_VBI_WSS_DATA0), + R_APB_REG(CVD2_VBI_WSS_DATA1), R_APB_REG(CVD2_VBI_DATA_STATUS)); return aspect_ratio; } @@ -3425,15 +3461,36 @@ cvd_store_err: /* return value: * true: signal stable - * false: signal not stable + * false: signal not stable or snow */ bool get_tvafe_signal_state(void) { + bool ret = false; struct tvafe_dev_s *devp = tvafe_get_dev(); - if (devp->tvafe.parm.info.status == TVIN_SIG_STATUS_STABLE) - return true; + if (tvafe_check_no_signal(&devp->tvafe.cvd2)) + ret = false; + else if (devp->tvafe.cvd2.info.state == TVAFE_CVD2_STATE_FIND && + devp->tvafe.parm.info.status == TVIN_SIG_STATUS_STABLE && + !(devp->flags & TVAFE_FLAG_DEV_SNOW_FLAG) && + !devp->tvafe.cvd2.hw.no_sig && + devp->tvafe.cvd2.info.isr_cnt > 3) + ret = true; else - return false; + ret = false; + + return ret; } EXPORT_SYMBOL(get_tvafe_signal_state); + +/* return enum tvin_sig_fmt_e */ +enum tvin_sig_fmt_e get_tvafe_signal_fmt(void) +{ + struct tvafe_dev_s *devp = tvafe_get_dev(); + + if (devp->tvafe.cvd2.info.state == TVAFE_CVD2_STATE_FIND) + return devp->tvafe.cvd2.config_fmt; + else + return TVIN_SIG_FMT_NULL; +} +EXPORT_SYMBOL(get_tvafe_signal_fmt); diff --git a/drivers/media/vin/tvin/tvafe/tvafe_cvd.h b/drivers/media/vin/tvin/tvafe/tvafe_cvd.h index d67c60902..063fcedb9 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_cvd.h +++ b/drivers/media/vin/tvin/tvafe/tvafe_cvd.h @@ -168,7 +168,6 @@ struct tvafe_cvd2_info_s { #endif unsigned int ntsc_switch_cnt; - unsigned int smr_cnt; unsigned int isr_cnt; unsigned int unlock_cnt; }; @@ -181,6 +180,7 @@ struct tvafe_cvd2_s { const unsigned int *acd_table; struct tvafe_reg_table_s *pq_conf; unsigned int fmt_loop_cnt; + unsigned int smr_cnt; unsigned int cvd_chroma_saturation; unsigned char hw_data_cur; enum tvin_port_e vd_port; @@ -232,6 +232,8 @@ void tvafe_cvd2_rf_ntsc50_en(bool v); void tvafe_cvd2_non_std_config(struct tvafe_cvd2_s *cvd2); int cvd_set_debug_parm(const char *buff, char **parm); bool get_tvafe_signal_state(void); +bool get_tvafe_signal_state(void); +enum tvin_sig_fmt_e get_tvafe_signal_fmt(void); extern bool tvafe_snow_function_flag; extern bool reinit_scan; diff --git a/drivers/media/vin/tvin/tvafe/tvafe_debug.c b/drivers/media/vin/tvin/tvafe/tvafe_debug.c index d09c9995c..a04d2ee90 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_debug.c +++ b/drivers/media/vin/tvin/tvafe/tvafe_debug.c @@ -79,6 +79,7 @@ static void tvafe_state(struct tvafe_dev_s *devp) tvafe_pr_info("tvafe_cvd2_s->cvd2_init_en:%d\n", cvd2->cvd2_init_en); tvafe_pr_info("tvafe_cvd2_s->nonstd_detect_dis:%d\n", cvd2->nonstd_detect_dis); + tvafe_pr_info("\n tvafe_cvd2_s->smr_cnt:%d\n", cvd2->smr_cnt); /* tvin_parm_s->tvin_info_s struct info */ tvafe_pr_info("\n!!tvin_parm_s->tvin_info_s struct info:\n"); tvafe_pr_info("tvin_info_s->trans_fmt:0x%x\n", tvin_info->trans_fmt); @@ -180,8 +181,6 @@ static void tvafe_state(struct tvafe_dev_s *devp) hw->noise_level); tvafe_pr_info("tvafe_cvd2_hw_data_s->low_amp:%d\n", hw->low_amp); - tvafe_pr_info("\n tvafe_cvd2_info_s->smr_cnt:%d\n", - cvd2_info->smr_cnt); tvafe_pr_info("tvafe_cvd2_info_s->isr_cnt:%d\n", cvd2_info->isr_cnt); tvafe_pr_info("tvafe_cvd2_info_s->unlock_cnt:%d\n\n", diff --git a/drivers/media/vin/tvin/tvafe/tvafe_regs.h b/drivers/media/vin/tvin/tvafe/tvafe_regs.h index 4d489af5b..28d4568f1 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_regs.h +++ b/drivers/media/vin/tvin/tvafe/tvafe_regs.h @@ -4141,6 +4141,14 @@ #define WSSJ_DELTA_AMPL_WID 8 #define CVD2_VBI_DATA_STATUS ((CVD_BASE_ADD + 0x65) << 2) +#define CC_RDY 0 +#define CC_RDY_WID 1 +#define WSS_RDY 1 +#define WSS_RDY_WID 1 +#define CC_RD_DONE 4 +#define CC_RD_DONE_WID 1 +#define WSS_RD_DONE 5 +#define WSS_RD_DONE_WID 1 #define CVD2_VBI_CC_LPF ((CVD_BASE_ADD + 0x66) << 2) #define CC_LPFIL_TRACK_GAIN_BIT 4 diff --git a/drivers/media/vin/tvin/tvafe/tvafe_vbi.c b/drivers/media/vin/tvin/tvafe/tvafe_vbi.c index c4a3fa000..e07b243d4 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_vbi.c +++ b/drivers/media/vin/tvin/tvafe/tvafe_vbi.c @@ -99,6 +99,15 @@ static unsigned int vbi_data_tt_check; #define VBI_VCNT_SEARCH_CNT_MAX 5 +/* manual reset vbi */ +static inline void vbi_manual_reset(void) +{ + W_APB_REG(ACD_REG_22, 0x07080000); + W_APB_REG(ACD_REG_22, 0x87080000); + W_APB_REG(ACD_REG_22, 0x04080000); + usleep_range(10, 12); +} + static void vbi_hw_reset(struct vbi_dev_s *devp) { /*W_VBI_APB_REG(ACD_REG_22, 0x82080000);*/ @@ -136,6 +145,12 @@ static void vbi_data_type_set(struct vbi_dev_s *devp) { unsigned int vbi_data_type = devp->vbi_data_type; + /* signal not stable not need set will set in vbi_slicer_work */ + if (devp->slicer->type >= VBI_TYPE_TT_625A && + devp->slicer->type <= VBI_TYPE_TT_525D && + !get_tvafe_signal_state()) + return; + /* data type */ W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE6, vbi_data_type); W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE7, vbi_data_type); @@ -154,11 +169,12 @@ static void vbi_data_type_set(struct vbi_dev_s *devp) W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE20, vbi_data_type); W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE21, vbi_data_type); W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE22, vbi_data_type); - if (devp->vbi_dto_wss != VBI_DTO_WSS625) - W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE23, vbi_data_type); - W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE24, vbi_data_type); - W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE25, vbi_data_type); - /*W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE26, vbi_data_type);*/ + if (devp->vbi_function_sel & VBI_CONFIG_NOT_VBI_LINE) { + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE23, vbi_data_type); //this line used wss + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE24, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE25, vbi_data_type); + /*W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE26, vbi_data_type);*/ + } } static void vbi_dto_set(struct vbi_dev_s *devp) @@ -197,12 +213,11 @@ static void vbi_slicer_type_set(struct vbi_dev_s *devp) devp->vbi_data_type = VBI_DATA_TYPE_EUROCC; devp->vbi_start_code = VBI_START_CODE_EUROCC; devp->vbi_dto_cc = VBI_DTO_EURCC; - /*line18 for PAL M*/ - W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE18, - VBI_DATA_TYPE_EUROCC); - /*line22 for PAL B,D,G,H,I,N,CN*/ - W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE22, - VBI_DATA_TYPE_EUROCC); + /* line18 for PAL M; line22 for PAL B,D,G,H,I,N,CN */ + if (get_tvafe_signal_fmt() == TVIN_SIG_FMT_CVBS_PAL_M) + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE18, VBI_DATA_TYPE_EUROCC); + else + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE22, VBI_DATA_TYPE_EUROCC); break; case VBI_TYPE_VPS: devp->vbi_data_type = VBI_DATA_TYPE_VPS; @@ -249,12 +264,11 @@ static void vbi_slicer_type_set(struct vbi_dev_s *devp) devp->vbi_data_type = VBI_DATA_TYPE_WSS625; devp->vbi_start_code = VBI_START_CODE_WSS625; devp->vbi_dto_wss = VBI_DTO_WSS625; - /*line17 for PAL M*/ - W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE17, - VBI_DATA_TYPE_WSS625); - /*line23 for PAL B,D,G,H,I,N,CN*/ - W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE23, - VBI_DATA_TYPE_WSS625); + /* line17 for PAL M; line23 for PAL B,D,G,H,I,N,CN */ + //W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE17, VBI_DATA_TYPE_WSS625); + if (get_tvafe_signal_fmt() == TVIN_SIG_FMT_CVBS_PAL_I || + get_tvafe_signal_fmt() == TVIN_SIG_FMT_CVBS_SECAM) + W_APB_REG(CVD2_VBI_DATA_TYPE_LINE23, VBI_DATA_TYPE_WSS625_ODD); break; case VBI_TYPE_WSSJ: devp->vbi_data_type = VBI_DATA_TYPE_WSSJ; @@ -284,7 +298,7 @@ static void vbi_slicer_type_set(struct vbi_dev_s *devp) W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE21, VBI_DATA_TYPE_TT_625B); W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE23, - VBI_DATA_TYPE_WSS625); + VBI_DATA_TYPE_WSS625_ODD); break; } if (slicer_type >= VBI_TYPE_TT_625A && @@ -917,35 +931,40 @@ static void vbi_tt_raw_data_test(struct vbi_data_s *vbi_data) /* vbi_is_not_valid_data; only check teletext * check whether has vbi data, empirical value * return value: - * true: not vbi data - * false: has vbi data + * true: vbi data + * false: not vbi data */ -static inline bool vbi_is_not_valid_data(struct vbi_data_s vbi_data) +static inline bool vbi_is_valid_data(struct vbi_data_s vbi_data) { - if (vbi_data.nbytes <= 2 && vbi_data.b[1] <= 0x3f) - return true; - else + if ((vbi_data.nbytes <= 2 && vbi_data.b[1] <= 0x3f) || + (vbi_data.nbytes == 42 && vbi_data.b[41] >= 0xf0)) return false; + else + return true; } static void vbi_check_is_valid_data(struct vbi_data_s vbi_data, struct vbi_dev_s *devp) { + if (devp->vbi_function_sel & VBI_BYPASS_CHECK_DATA) + return; + if (devp->slicer->type < VBI_TYPE_TT_625A || devp->slicer->type > VBI_TYPE_TT_525D) return; if (devp->no_rcv_data_enable) { - if (!vbi_is_not_valid_data(vbi_data)) { + if (vbi_is_valid_data(vbi_data) && get_tvafe_signal_state()) { devp->rcv_data_cnt++; devp->no_rcv_data_cnt = 0; } else { devp->rcv_data_cnt = 0; } } else { - if (vbi_is_not_valid_data(vbi_data)) { - devp->no_rcv_data_cnt++; + if (!vbi_is_valid_data(vbi_data) || !get_tvafe_signal_state()) { devp->rcv_data_cnt = 0; - if (vbi_data.line_num == 23) //quick detected not data + if (!get_tvafe_signal_state()) + devp->no_rcv_data_cnt += (VBI_NO_DATA_CNT >> 1); + else devp->no_rcv_data_cnt++; } else { devp->no_rcv_data_cnt = 0; @@ -960,22 +979,104 @@ static void vbi_check_is_data_rev(struct vbi_dev_s *devp) devp->no_rcv_data_enable = false; devp->rcv_data_cnt = 0; devp->no_rcv_data_cnt = 0; - if (vbi_dbg_en & VBI_DBG_ISR4) - pr_info("%s:rcv data no_rcv_data_enable:%d\n", - __func__, devp->no_rcv_data_enable); + pr_info("%s:rcv data no_rcv_data_enable:%d\n", + __func__, devp->no_rcv_data_enable); } } else { if (devp->no_rcv_data_cnt > VBI_NO_DATA_CNT) { + memset(devp->pac_addr_start, 0, devp->mem_size); + if (vbi_mem_flag == VBI_MEM_CODEC_MALLOC) + codec_mm_dma_flush(devp->pac_addr_start, + devp->mem_size, DMA_TO_DEVICE); devp->no_rcv_data_enable = true; devp->rcv_data_cnt = 0; devp->no_rcv_data_cnt = 0; - if (vbi_dbg_en & VBI_DBG_ISR4) - pr_info("%s:no rcv data no_rcv_data_enable:%d\n", - __func__, devp->no_rcv_data_enable); + pr_info("%s:not rcv data no_rcv_data_enable:%d\n", + __func__, devp->no_rcv_data_enable); } } } +/* vbi_set_tt_type_enable + * return value: + * true: has reset vbi + * false: not reset vbi + */ +static bool vbi_set_tt_type_enable(bool enable) +{ + struct vbi_dev_s *devp = vbi_dev_local; + unsigned int vbi_data_type; + bool ret = false; + + if (!devp) + return false; + + if (devp->vbi_function_sel & VBI_BYPASS_CHECK_DATA) + return false; + + if (devp->slicer->type < VBI_TYPE_TT_625A || + devp->slicer->type > VBI_TYPE_TT_525D || + !devp->slicer_enable) + return false; + + vbi_data_type = devp->vbi_data_type; + if (enable) { + if (!R_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE6)) { + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE6, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE7, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE8, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE9, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE10, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE11, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE12, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE13, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE14, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE15, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE16, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE17, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE18, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE19, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE20, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE21, vbi_data_type); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE22, vbi_data_type); + vbi_manual_reset(); + memset(devp->pac_addr_start, 0, devp->mem_size); + if (vbi_mem_flag == VBI_MEM_CODEC_MALLOC) + codec_mm_dma_flush(devp->pac_addr_start, + devp->mem_size, DMA_TO_DEVICE); + pr_info("%s:set data type:%d enable:%d vbi_type:%d\n", __func__, + devp->slicer->type, devp->slicer_enable, devp->vbi_data_type); + ret = true; + } + } else { + if (R_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE6)) { + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE6, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE7, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE8, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE9, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE10, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE11, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE12, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE13, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE14, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE15, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE16, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE17, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE18, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE19, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE20, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE21, 0); + W_VBI_APB_REG(CVD2_VBI_DATA_TYPE_LINE22, 0); + vbi_manual_reset(); + vbi_ringbuffer_flush(&devp->slicer->buffer); + pr_info("%s:close data type:%d enable:%d vbi_type:%d\n", __func__, + devp->slicer->type, devp->slicer_enable, devp->vbi_data_type); + ret = true; + } + } + return ret; +} + static void vbi_slicer_work(struct work_struct *p_work) { struct vbi_dev_s *devp = vbi_dev_local; @@ -1011,6 +1112,23 @@ static void vbi_slicer_work(struct work_struct *p_work) return; } + /* if not sig close tt data type */ + if (devp->slicer->type >= VBI_TYPE_TT_625A && + devp->slicer->type <= VBI_TYPE_TT_525D) { + if (get_tvafe_signal_state()) { + //guarantee vbi_data_type set + if (vbi_set_tt_type_enable(true)) { + mutex_unlock(&devp->slicer->mutex); + return; + } + } else { + if (vbi_set_tt_type_enable(false)) { + mutex_unlock(&devp->slicer->mutex); + return; + } + } + } + if (devp->slicer->busy) { if (vbi_dbg_en & VBI_DBG_INFO) tvafe_pr_info("%s busy, exit\n", __func__); @@ -1074,10 +1192,13 @@ static void vbi_slicer_work(struct work_struct *p_work) tvafe_pr_info("%s: no vbi data, len %d, vcnt:%d\n", __func__, len, vcnt); } - if (devp->slicer->type >= VBI_TYPE_TT_625A && + if (!(devp->vbi_function_sel & VBI_BYPASS_CHECK_DATA) && + devp->slicer->type >= VBI_TYPE_TT_625A && devp->slicer->type <= VBI_TYPE_TT_525D && - !devp->no_rcv_data_enable) + !devp->no_rcv_data_enable) { + devp->rcv_data_cnt = 0; devp->no_rcv_data_cnt++; + } goto vbi_slicer_work_next; } @@ -1168,6 +1289,15 @@ static void vbi_slicer_work(struct work_struct *p_work) } continue; } + if (!(devp->vbi_function_sel & VBI_CONFIG_NOT_VBI_LINE) && + (vbi_data.vbi_type == VBI_ID_WSS625 || + vbi_data.vbi_type == VBI_ID_WSSJ)) { + if (vbi_dbg_en & VBI_DBG_INFO2) { + tvafe_pr_info("[vbi..]: vcnt:%d, ch_len:%d, type:%d wss data\n", + vcnt, ch_len, vbi_data.vbi_type); + } + continue; + } /* byte counter */ vbi_get_byte(&local_rptr, &rbyte); ch_len++; @@ -1220,9 +1350,10 @@ static void vbi_slicer_work(struct work_struct *p_work) if (vbi_dbg_en & VBI_DBG_ISR4) { if (vbi_pr_isr_buf) { j = sprintf(vbi_pr_isr_buf, - "[vbi..]: ch_len:%d, vcnt:%d, field_id:%d, line_num:%4d, data_cnt:%d:", - ch_len, vcnt, + "[vbi..]:%d ch_len:%d, vcnt:%d, field_id:%d:%d, line_num:%4d, data_cnt:%d:", + get_tvafe_signal_state(), ch_len, vcnt, vbi_data.field_id, + vbi_data.vbi_type, vbi_data.line_num, vbi_data.nbytes); for (i = 0; i < vbi_data.nbytes ; i++) { @@ -1440,20 +1571,14 @@ static int vbi_slicer_set(struct vbi_dev_s *vbi_dev, return 0;/* vbi_slicer_start(vbi_dev); */ } -/* manual reset vbi */ -static void vbi_manual_reset(void) -{ - W_APB_REG(ACD_REG_22, 0x07080000); - W_APB_REG(ACD_REG_22, 0x87080000); - W_APB_REG(ACD_REG_22, 0x04080000); - usleep_range(10, 12); -} - void tvafe_vbi_set_wss(void) { struct vbi_dev_s *devp = vbi_dev_local; - if (tvafe_clk_status && devp) { + if (!devp || devp->vbi_function_sel & VBI_BYPASS_WSS_SET) + return; + + if (tvafe_clk_status) { devp->slicer->type = VBI_TYPE_WSS625; vbi_slicer_type_set(devp); vbi_manual_reset(); @@ -1516,9 +1641,10 @@ static void vbi_user_buffer_dump(u8 __user *buf, size_t len) } j = sprintf(vbi_pr_read_buf, - "[user..]: ch_len:%d, field_id:%d, line_num:%4d, data_cnt:%d:", + "[user..]: ch_len:%d, field_id:%d:%d, line_num:%4d, data_cnt:%d:", ch_len, vbi_data.field_id, + vbi_data.vbi_type, vbi_data.line_num, vbi_data.nbytes); for (i = 0; i < vbi_data.nbytes ; i++) { @@ -1619,12 +1745,10 @@ static ssize_t vbi_buffer_read(struct vbi_dev_s *vbi_dev, __func__, src->pread, src->pwrite); return ret; } - - /* fake data get return no data */ - if (vbi_dev->no_rcv_data_enable || !get_tvafe_signal_state()) { + if (vbi_dev->no_rcv_data_enable) { if (vbi_dbg_en & VBI_DBG_READ) - tvafe_pr_info("[vbi..]%s: no data rcv_data:%d stable:%d\n", - __func__, vbi_dev->no_rcv_data_enable, get_tvafe_signal_state()); + tvafe_pr_info("[vbi..]%s:vbi not data %d-%d\n", + __func__, src->pread, src->pwrite); return 0; } @@ -2140,6 +2264,7 @@ static ssize_t debug_store(struct device *dev, tvafe_pr_info("mem_start:0x%p,pac_addr_start:0x%p,pac_addr_end:0x%p\n", devp->pac_addr, devp->pac_addr_start, devp->pac_addr_end); + tvafe_pr_info("vbi_function_sel:%#x\n", devp->vbi_function_sel); if (vbi_slicer) tvafe_pr_info("vbi_slicer:type:%d,state:%d\n", vbi_slicer->type, vbi_slicer->state); @@ -2240,6 +2365,7 @@ static ssize_t debug_store(struct device *dev, /* vbi reset release, vbi agent enable*/ W_VBI_APB_REG(ACD_REG_22, 0x06080000); W_VBI_APB_REG(CVD2_VBI_FRAME_CODE_CTL, 0x10); + tvafe_vbi_set_wss(); tvafe_pr_info(" disable vbi function\n"); tvafe_pr_info("stop done!!!\n"); } else if (!strncmp(parm[0], "set_size", strlen("set_size"))) { @@ -2305,6 +2431,15 @@ static ssize_t debug_store(struct device *dev, goto vbi_store_err; vbi_read_wakeup_interval = val; tvafe_pr_info("vbi_dbg_print_cnt:%d\n", vbi_read_wakeup_interval); + } else if (!strncmp(parm[0], "vbi_function_sel", strlen("vbi_function_sel"))) { + if (!parm[1]) { + tvafe_pr_info("error: miss dump file name!\n"); + goto vbi_store_exit; + } + if (kstrtouint(parm[1], 16, &val) < 0) + goto vbi_store_err; + devp->vbi_function_sel = val; + tvafe_pr_info("vbi_function_sel:%#x\n", devp->vbi_function_sel); } else { tvafe_pr_info("[vbi..]unsupport cmd!!!\n"); } @@ -2476,6 +2611,7 @@ static int vbi_probe(struct platform_device *pdev) spin_lock_init(&vbi_dev->slicer->buffer.lock); vbi_dev->slicer->buffer.data = NULL; vbi_dev->slicer->state = VBI_STATE_FREE; + vbi_dev->vbi_function_sel |= VBI_BYPASS_CHECK_DATA;//close check wheather has teletext res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res) { diff --git a/drivers/media/vin/tvin/tvafe/tvafe_vbi.h b/drivers/media/vin/tvin/tvafe/tvafe_vbi.h index 4d3d54975..516995988 100644 --- a/drivers/media/vin/tvin/tvafe/tvafe_vbi.h +++ b/drivers/media/vin/tvin/tvafe/tvafe_vbi.h @@ -63,6 +63,7 @@ #define VBI_DATA_TYPE_TT_525C 0xaa #define VBI_DATA_TYPE_TT_525D 0xbb #define VBI_DATA_TYPE_WSS625 0xcc +#define VBI_DATA_TYPE_WSS625_ODD 0x0c //only odd field 23 line value #define VBI_DATA_TYPE_WSSJ 0xdd /* vbi start code,TT start code is programmable by software,*/ @@ -117,8 +118,14 @@ #define VBI_LINE_MIN 6 #define VBI_LINE_MAX 25 -#define VBI_NO_DATA_CNT 15 -#define VBI_HAS_DATA_CNT 2 +#define VBI_NO_DATA_CNT 16 +#define VBI_HAS_DATA_CNT 9 + +/* vbi_function_sel control bits start */ +#define VBI_BYPASS_WSS_SET BIT(0) +#define VBI_BYPASS_CHECK_DATA BIT(1) //check whether has teletext data +#define VBI_CONFIG_NOT_VBI_LINE BIT(2) +/* vbi_function_sel control bits end */ enum vbi_package_type_e { VBI_PACKAGE_CC1 = 1, @@ -287,6 +294,7 @@ struct vbi_dev_s { spinlock_t lock; /* slicer buffer lock */ struct timer_list timer; bool slicer_enable; + unsigned int vbi_function_sel; unsigned int isr_cnt; }; @@ -295,7 +303,7 @@ struct vbi_dev_s { /*0: tvafe clk disable*/ /*read write cvd acd reg will crash when clk disabled*/ extern bool tvafe_clk_status; -extern unsigned int vbi_mem_start; +extern unsigned long vbi_mem_start; void tvafe_vbi_set_wss(void); #endif /* TVIN_VBI_H_ */ diff --git a/drivers/media/vin/tvin/tvin_frontend.h b/drivers/media/vin/tvin/tvin_frontend.h index e66de8a64..694c72b74 100644 --- a/drivers/media/vin/tvin/tvin_frontend.h +++ b/drivers/media/vin/tvin/tvin_frontend.h @@ -77,6 +77,7 @@ struct tvin_state_machine_ops_s { void (*hdmi_reset_pcs)(struct tvin_frontend_s *fe); void (*hdmi_de_hactive)(bool en, struct tvin_frontend_s *fe); bool (*hdmi_clr_pkts)(struct tvin_frontend_s *fe); + void (*frontend_clr_value)(struct tvin_frontend_s *fe); }; struct tvin_frontend_s { diff --git a/drivers/media/vin/tvin/tvin_global.h b/drivers/media/vin/tvin/tvin_global.h index 43eafd2c3..a995b70b8 100644 --- a/drivers/media/vin/tvin/tvin_global.h +++ b/drivers/media/vin/tvin/tvin_global.h @@ -369,6 +369,7 @@ enum tvin_ar_b3_b0_val_e { TVIN_AR_16x9_LB_CENTER_VAL = 0xb, TVIN_AR_16x9_LB_CENTER1_VAL = 0xd, TVIN_AR_14x9_FULL_VAL = 0xe, + TVIN_AR_NOT_VALUE = 0xf, }; const char *tvin_aspect_ratio_str(enum tvin_aspect_ratio_e aspect_ratio); diff --git a/drivers/media/vin/tvin/vdin/vdin_ctl.c b/drivers/media/vin/tvin/vdin/vdin_ctl.c index b44efd9e3..3e3b77ee9 100644 --- a/drivers/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/media/vin/tvin/vdin/vdin_ctl.c @@ -6980,6 +6980,10 @@ void vdin_set_display_ratio(struct vdin_dev_s *devp, vf->ratio_control = 0x0 << DISP_RATIO_ASPECT_RATIO_BIT; } + if ((devp->vdin_function_sel & VDIN_ONLY_SEND_WSS_VALUE) && + IS_TVAFE_SRC(devp->parm.port)) + aspect_ratio = TVIN_ASPECT_NULL; + switch (aspect_ratio) { case TVIN_ASPECT_4x3_FULL: /* vf->width*vf->sar_width : vf->height*vf->sar_height = 4 : 3 */ diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.c b/drivers/media/vin/tvin/vdin/vdin_drv.c index a1c9de4e3..ed8305842 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/media/vin/tvin/vdin/vdin_drv.c @@ -1581,6 +1581,10 @@ void vdin_stop_dec(struct vdin_dev_s *devp) disable_irq(devp->vdin2_meta_wr_done_irq); devp->flags &= (~VDIN_FLAG_ISR_EN); + /* for wss value not clear when snow */ + if (IS_TVAFE_SRC(devp->parm.port) && devp->frontend && + devp->frontend->sm_ops->frontend_clr_value) + devp->frontend->sm_ops->frontend_clr_value(devp->frontend); pr_info("%s vdin%d,delay %u us before stop\n", __func__, devp->index, devp->dbg_stop_dec_delay); @@ -4579,8 +4583,9 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ret = -EFAULT; if (vdin_dbg_en) - pr_info("%s signal_type: 0x%x,status:0x%x,fr:%d,fmt:%#x\n", - __func__, info.signal_type, info.status, info.fps, info.fmt); + pr_info("%s signal_type: 0x%x,status:0x%x,fr:%d ratio:%d\n", + __func__, info.signal_type, info.status, info.fps, + info.aspect_ratio); mutex_unlock(&devp->fe_lock); break; } diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.h b/drivers/media/vin/tvin/vdin/vdin_drv.h index abb20290c..2a90a4ae2 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.h +++ b/drivers/media/vin/tvin/vdin/vdin_drv.h @@ -332,6 +332,7 @@ struct match_data_s { #define VDIN_ADJUST_VLOCK BIT(4) #define VDIN_GAME_NOT_TANSFER BIT(6) //control for tx output when game mode #define VDIN_FORCE_444_NOT_CONVERT BIT(7) //commercial display control +#define VDIN_ONLY_SEND_WSS_VALUE BIT(8) //vdin send aspect ratio value #define VDIN_SET_DISPLAY_RATIO BIT(9) #define VDIN_NOT_DATA_INPUT_DROP BIT(10) #define VDIN_BYPASS_HDR_SEI_CHECK BIT(11) //bypass Non-standard hdr stream detection diff --git a/drivers/media/vin/tvin/vdin/vdin_sm.c b/drivers/media/vin/tvin/vdin/vdin_sm.c index ea37ea65f..1c66f8f39 100644 --- a/drivers/media/vin/tvin/vdin/vdin_sm.c +++ b/drivers/media/vin/tvin/vdin/vdin_sm.c @@ -405,9 +405,7 @@ static enum tvin_sg_chg_flg vdin_hdmirx_fmt_chg_detect(struct vdin_dev_s *devp) devp->sg_chg_fps_cnt = 0; } - if (devp->pre_prop.aspect_ratio != - devp->prop.aspect_ratio && - IS_HDMI_SRC(devp->parm.port)) { + if (devp->pre_prop.aspect_ratio != devp->prop.aspect_ratio) { if (devp->sg_chg_afd_cnt > 1) { signal_chg |= TVIN_SIG_CHG_AFD; if (signal_chg)