vdin: sync bug fixes code from projects [1/1]

PD#SWPL-128695

Problem:
fixed some issues on projects,need sync back into trunk
1.game mode switch cause video freezing
2.app start decoder with wrong args casue problem
3.rx signal changed fast cause app got wrong vrr state
4.app may call ioctl to control in v4l2 mode
5.vdin vsync abnormal cause afbce memory access violation

Solution:
1.recycle vf after game mode change
2.improve driver workflow
3.improve signal detect flow
4.add ioctl args check when in v4l2 mode
5.filtering abnormal vdin vsync

Verify:
t7/t5m

Change-Id: I90be40c1a16239f63dc682a34bde2b920128e62e
Signed-off-by: haitao.liu <haitao.liu@amlogic.com>
This commit is contained in:
haitao.liu
2023-06-19 19:36:49 +08:00
committed by gerrit autosubmit
parent 6403737bed
commit 6822acbaed
9 changed files with 224 additions and 108 deletions
+70 -10
View File
@@ -170,7 +170,7 @@ void vdin_write_mif_or_afbce_init(struct vdin_dev_s *devp)
W_VCBUS_BIT(VDIN_MISC_CTRL, 1, VDIN0_OUT_AFBCE_BIT, 1);
}
W_VCBUS_BIT(AFBCE_ENABLE, 1, AFBCE_EN_BIT, AFBCE_EN_WID);
W_VCBUS_BIT(AFBCE_ENABLE, 0, AFBCE_EN_BIT, AFBCE_EN_WID);
}
}
@@ -501,10 +501,10 @@ void vdin_afbce_config(struct vdin_dev_s *devp)
(((def_color_1 << bit_mode_shift) & 0xfff) << 0));
if (devp->dtdata->hw_ver >= VDIN_HW_T7)
W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4,
devp->afbce_info->table_paddr >> 4, 0, 32);//table_paddr?
devp->afbce_info->fm_table_paddr[0] >> 4, 0, 32);
else
W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4,
devp->afbce_info->table_paddr, 0, 32);
devp->afbce_info->fm_table_paddr[0], 0, 32);
W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, cur_mmu_used, 0, 12);
/*for almost uncompressed pattern,garbage at bottom
@@ -514,12 +514,12 @@ void vdin_afbce_config(struct vdin_dev_s *devp)
*/
W_VCBUS_BIT(AFBCE_MMU_RMIF_SCOPE_X, 0x1c4f, 16, 13);
W_VCBUS_BIT(AFBCE_ENABLE, 1, AFBCE_WORK_MD_BIT, AFBCE_WORK_MD_WID);
W_VCBUS_BIT(AFBCE_ENABLE, 0, AFBCE_WORK_MD_BIT, AFBCE_WORK_MD_WID);
if (devp->double_wr)
W_VCBUS_BIT(AFBCE_ENABLE, 1, AFBCE_EN_BIT, AFBCE_EN_WID);
else
W_VCBUS_BIT(AFBCE_ENABLE, 0, AFBCE_EN_BIT, AFBCE_EN_WID);
// if (devp->double_wr)
// W_VCBUS_BIT(AFBCE_ENABLE, 1, AFBCE_EN_BIT, AFBCE_EN_WID);
// else
// W_VCBUS_BIT(AFBCE_ENABLE, 0, AFBCE_EN_BIT, AFBCE_EN_WID);
if (devp->debug.dbg_print_cntl & VDIN_ADDRESS_DBG &&
devp->irq_cnt < VDIN_DBG_PRINT_CNT)
@@ -606,6 +606,47 @@ void vdin_afbce_maptable_init(struct vdin_dev_s *devp)
}
}
static void vdin_afbce_addr_check(struct vdin_dev_s *devp, unsigned long fm_table_paddr)
{
unsigned int i = 0, j, cnt = 0;
unsigned int *virt_addr = NULL;
unsigned int body;
unsigned int size;
if (!devp->afbce_info)
return;
if (devp->mem_type == VDIN_MEM_TYPE_SCT) {
pr_info("%s,use VDIN_MEM_TYPE_SCT\n", __func__);
return;
}
size = roundup(devp->afbce_info->frame_body_size, 4096);
for (i = 0; i < devp->vf_mem_max_cnt; i++) {
if (!devp->afbce_info->fm_table_paddr[i])
return;
if (fm_table_paddr == devp->afbce_info->fm_table_paddr[i])
break;
}
if (i >= devp->vf_mem_max_cnt)
return;
pr_err("fm_idx:%d,table val(%#lx)\n", i, fm_table_paddr);
virt_addr = phys_to_virt(fm_table_paddr);
body = devp->afbce_info->fm_body_paddr[i] & 0xffffffff;
for (j = 0; j < size; j += 4096) {
if ((*virt_addr != (((j + body) >> 12) & 0x000fffff)) ||
(devp->debug.dbg_print_cntl & VDIN_AFBC_RD_DBG)) {
pr_err("offset[%#x] should be:(%#x),readback:(%#x)\n",
cnt, (((j + body) >> 12) & 0x000fffff), *virt_addr);
}
cnt++;
virt_addr++;
}
}
void vdin_afbce_set_next_frame(struct vdin_dev_s *devp,
unsigned int rdma_enable, struct vf_entry *vfe)
{
@@ -650,17 +691,34 @@ void vdin_afbce_set_next_frame(struct vdin_dev_s *devp,
else
rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 1,
AFBCE_EN_BIT, AFBCE_EN_WID);
} else {
if (devp->dtdata->hw_ver >= VDIN_HW_T7) {
W_VCBUS(AFBCE_HEAD_BADDR,
devp->afbce_info->fm_head_paddr[i] >> 4);
W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4,
devp->afbce_info->fm_table_paddr[i] >> 4,
0, 32);
} else {
W_VCBUS(AFBCE_HEAD_BADDR,
devp->afbce_info->fm_head_paddr[i]);
W_VCBUS_BIT(AFBCE_MMU_RMIF_CTRL4,
devp->afbce_info->fm_table_paddr[i],
0, 32);
}
}
#endif
vdin_afbce_clear_write_down_flag(devp);
if (devp->debug.dbg_print_cntl & VDIN_ADDRESS_DBG &&
devp->irq_cnt < VDIN_DBG_PRINT_CNT)
devp->irq_cnt < VDIN_DBG_PRINT_CNT) {
pr_err("%s %#x:%#x(%#lx) %#x:%#x(%#lx)\n",
__func__, AFBCE_HEAD_BADDR, rd(0, AFBCE_HEAD_BADDR),
devp->afbce_info->fm_head_paddr[i],
AFBCE_MMU_RMIF_CTRL4, rd(0, AFBCE_MMU_RMIF_CTRL4),
AFBCE_MMU_RMIF_CTRL4, rd(0, AFBCE_MMU_RMIF_CTRL4) << 4,
devp->afbce_info->fm_table_paddr[i]);
if (devp->debug.dbg_print_cntl & VDIN_AFBC_ADDR_CHK)
vdin_afbce_addr_check(devp, rd(0, AFBCE_MMU_RMIF_CTRL4) << 4);
}
}
void vdin_pause_afbce_write(struct vdin_dev_s *devp, unsigned int rdma_enable)
@@ -676,6 +734,8 @@ void vdin_pause_afbce_write(struct vdin_dev_s *devp, unsigned int rdma_enable)
if (rdma_enable)
rdma_write_reg_bits(devp->rdma_handle, AFBCE_ENABLE, 0,
AFBCE_EN_BIT, AFBCE_EN_WID);
else
W_VCBUS_BIT(AFBCE_ENABLE, 0, AFBCE_EN_BIT, AFBCE_EN_WID);
#endif
vdin_afbce_clear_write_down_flag(devp);
}
@@ -850,6 +850,10 @@ unsigned int vdin_cma_alloc(struct vdin_dev_s *devp)
devp->index, i,
devp->afbce_info->fm_table_paddr[i],
devp->afbce_info->frame_table_size);
pr_info("vdin%d fm_body_paddr[%d]=0x%lx, frame_body_size = 0x%x\n",
devp->index, i,
devp->afbce_info->fm_body_paddr[i],
devp->afbce_info->frame_body_size);
}
}
}
+7 -1
View File
@@ -6257,9 +6257,15 @@ bool vdin_check_spd_data_chg(struct vdin_dev_s *devp)
(devp->prop.spd_data.data[0] == 0x1a &&
devp->prop.spd_data.data[1] == 0x00 &&
devp->prop.spd_data.data[2] == 0x00)) {
/* If freesync states changed or the current state is not the same as
* application got before,report change event.
*/
if ((devp->pre_prop.spd_data.data[5] >> 2 & 0x3) !=
(devp->prop.spd_data.data[5] >> 2 & 0x3))
(devp->prop.spd_data.data[5] >> 2 & 0x3) ||
(devp->prop.spd_data.data[5] >> 2 & 0x3) !=
(devp->vrr_data.cur_spd_data5 >> 2 & 0x3)) {
return true;
}
} else {
return false;
}
+3
View File
@@ -97,6 +97,9 @@
#define MEM_ALLOC_FROM_CODEC (BIT(0))
#define VDIN_ADDRESS_DBG BIT(0)
#define VDIN_AFBC_RD_DBG BIT(1)
#define VDIN_AFBC_ADDR_CHK BIT(2)
#define VDIN_DBG_PRINT_CNT 20
/* 8 is filter the abnormal frame rate diff */
+112 -84
View File
@@ -283,7 +283,7 @@ void tvin_update_vdin_prop(void)
struct vdin_dev_s *vdin0_devp = vdin_devp[0];
ulong flags;
if (!vdin0_devp ||
if (!vdin0_devp || !vdin0_devp->frontend ||
!(vdin0_devp->flags & VDIN_FLAG_ISR_EN))
return;
@@ -403,7 +403,7 @@ int vdin_open_fe(enum tvin_port_e port, int index, struct vdin_dev_s *devp)
void vdin_close_fe(struct vdin_dev_s *devp)
{
/* avoid null pointer oops */
if (!devp || !devp->frontend) {
if (!devp) {
pr_info("%s: null pointer\n", __func__);
return;
}
@@ -804,29 +804,8 @@ static void vdin_game_mode_transfer(struct vdin_dev_s *devp)
static void vdin_handle_game_mode_chg(struct vdin_dev_s *devp)
{
if (devp->game_mode_chg == VDIN_GAME_MODE_OFF_TO_ON ||
devp->game_mode_chg == VDIN_GAME_MODE_1_TO_2) {
if (vdin_isr_monitor & VDIN_ISR_MONITOR_GAME)
pr_info("%s,game_mode_cur:%d,last_wr_vfe:%d\n", __func__,
devp->game_mode, !!devp->last_wr_vfe);
if ((devp->game_mode & VDIN_GAME_MODE_1) && devp->last_wr_vfe) {
receiver_vf_put(&devp->last_wr_vfe->vf, devp->vfp);
devp->last_wr_vfe = NULL;
}
} else if (devp->game_mode_chg == VDIN_GAME_MODE_ON_TO_OFF) {
if ((devp->game_mode_bak & VDIN_GAME_MODE_1) && devp->curr_wr_vfe)
receiver_vf_put(&devp->curr_wr_vfe->vf, devp->vfp);
if ((devp->game_mode_bak & VDIN_GAME_MODE_1) ||
(devp->game_mode_bak & VDIN_GAME_MODE_2)) {
devp->curr_wr_vfe = NULL;
devp->last_wr_vfe = NULL;
devp->game_chg_drop_frame_cnt = 2;
}
if (vdin_isr_monitor & VDIN_ISR_MONITOR_GAME)
pr_info("%s,game_mode_chg:%d,game_mode_bak:%#x\n", __func__,
devp->game_mode_chg, devp->game_mode_bak);
} else if (devp->game_mode_chg == VDIN_GAME_MODE_2_TO_1) {
if (devp->game_mode_chg != VDIN_GAME_MODE_UN_CHG &&
devp->game_mode_chg < VDIN_GAME_MODE_NUM) {
if (devp->curr_wr_vfe)
receiver_vf_put(&devp->curr_wr_vfe->vf, devp->vfp);
devp->curr_wr_vfe = NULL;
@@ -1175,7 +1154,7 @@ int vdin_start_dec(struct vdin_dev_s *devp)
pr_info("%s dv:%d hdr:%d allm:0x%x fps:%d sg_type:0x%x ratio:%d,vrr:%d prop_vrr:%d,%d\n",
__func__,
devp->dv.dv_flag, devp->prop.vdin_hdr_flag,
devp->pre_prop.latency.allm_mode, devp->prop.fps,
devp->prop.latency.allm_mode, devp->prop.fps,
devp->parm.info.signal_type,
devp->parm.info.aspect_ratio,
devp->vrr_data.vdin_vrr_en_flag,
@@ -1319,6 +1298,7 @@ int vdin_start_dec(struct vdin_dev_s *devp)
devp->dv.chg_cnt = 0;
devp->prop.hdr_info.hdr_check_cnt = 0;
devp->vrr_data.vrr_chg_cnt = 0;
devp->vrr_data.cur_spd_data5 = devp->prop.spd_data.data[5];
devp->last_wr_vfe = NULL;
irq_max_count = 0;
vdin_drop_cnt = 0;
@@ -1410,7 +1390,10 @@ int vdin_start_dec(struct vdin_dev_s *devp)
devp->put_frame_cnt = 0;
phase_lock_flag = 0;
devp->ignore_frames = max_ignore_frame_cnt;
devp->vs_time_stamp = sched_clock();
if (devp->parm.info.fps)
devp->vs_time_stamp = (1000 * 50000) / devp->parm.info.fps;
else
devp->vs_time_stamp = sched_clock();
devp->unreliable_vs_cnt = 0;
devp->unreliable_vs_cnt_pre = 0;
devp->unreliable_vs_idx = 0;
@@ -1508,7 +1491,7 @@ void vdin_stop_dec(struct vdin_dev_s *devp)
int i = 0;
#endif
/* avoid null pointer oops */
if (!devp || !devp->frontend) {
if (!devp) {
pr_info("vdin err no frontend\n");
return;
}
@@ -1587,6 +1570,7 @@ void vdin_stop_dec(struct vdin_dev_s *devp)
pr_info("linux system switch pc/game not need stop\n");
} else {
if (!(devp->parm.flag & TVIN_PARM_FLAG_CAP) &&
devp->frontend &&
devp->frontend->dec_ops &&
devp->frontend->dec_ops->stop &&
((!IS_TVAFE_ATV_SRC(devp->parm.port)) ||
@@ -2441,12 +2425,14 @@ irqreturn_t vdin_isr_simple(int irq, void *dev_id)
last_field_type = devp->curr_field_type;
devp->curr_field_type = vdin_get_curr_field_type(devp);
dec_ops = devp->frontend->dec_ops;
if (dec_ops->decode_isr(devp->frontend,
vdin_get_meas_h_cnt64(devp->addr_offset)) == -1)
return IRQ_HANDLED;
/* set canvas address */
if (devp->frontend) {
dec_ops = devp->frontend->dec_ops;
if (dec_ops->decode_isr(devp->frontend,
vdin_get_meas_h_cnt64(devp->addr_offset)) == -1)
return IRQ_HANDLED;
}
/* set canvas address */
vdin_set_canvas_id(devp, devp->flags & VDIN_FLAG_RDMA_ENABLE, NULL);
if (vdin_dbg_en)
pr_info("%2d: canvas id %d, field type %s\n",
@@ -2515,16 +2501,12 @@ static void vdin_hist_tgt(struct vdin_dev_s *devp, struct vframe_s *vf)
void vdin_drop_frame_info(struct vdin_dev_s *devp, char *info)
{
if (skip_frame_debug) {
if (devp->vdin_irq_flag == VDIN_IRQ_FLG_NO_NEXT_FE)
pr_info("vdin.%d: %s wr_list:%x wr_mode:%x rd_list:%x rd_mode:%x\n",
devp->index, info, devp->vfp->wr_list_size,
devp->vfp->wr_mode_size, devp->vfp->rd_list_size,
devp->vfp->rd_mode_size);
else
pr_info("vdin.%d: vdin_irq_flag=%d %s\n",
devp->index, devp->vdin_irq_flag, info);
}
if (skip_frame_debug)
pr_info("vdin%d[%d %d]:irq_flag:%d %s [%d %d],WL:%x WR:%x RL:%x RM:%x\n",
devp->index, devp->irq_cnt, devp->frame_cnt, devp->vdin_irq_flag, info,
devp->irq_cnt, devp->frame_cnt,
devp->vfp->wr_list_size, devp->vfp->wr_mode_size,
devp->vfp->rd_list_size, devp->vfp->rd_mode_size);
}
int vdin_vs_duration_check(struct vdin_dev_s *devp)
@@ -2542,20 +2524,22 @@ int vdin_vs_duration_check(struct vdin_dev_s *devp)
if (vdin_isr_monitor & VDIN_ISR_MONITOR_VS)
pr_info("isr:diff_time:%d, cycle:%d\n",
diff_time, devp->cycle);
/* more than 2 rate is unreliable vs need drop */
if (devp->irq_cnt > 2 && devp->irq_cnt < 0xff && diff_time > 0x186a0) {
/* In a duration 50M clk theory value */
if (devp->parm.info.fps)
devp->vs_time_stamp = (1000 * 50000) / devp->parm.info.fps;
else
devp->vs_time_stamp = cur_time;
if (diff_time > 0x186a0) {
temp = diff_time;
if (devp->unreliable_vs_idx >= 10)
devp->unreliable_vs_idx = 0;
devp->unreliable_vs_time[devp->unreliable_vs_idx] = temp;
devp->unreliable_vs_idx++;
/* In a duration 50M clk theory value */
devp->vs_time_stamp = (1000 * 50000) / devp->parm.info.fps;
return -1;
}
devp->vs_time_stamp = cur_time;
return ret;
}
@@ -2585,7 +2569,7 @@ int vdin_vframe_put_and_recycle(struct vdin_dev_s *devp, struct vf_entry *vfe,
receiver_vf_put(&vfe->vf, devp->vfp);
ret = -1;
} else if (devp->game_chg_drop_frame_cnt > 0) {
if (vfe)
if (vfe && !(vfe->flag & VF_FLAG_ONE_BUFFER_MODE))
receiver_vf_put(&vfe->vf, devp->vfp);
devp->game_chg_drop_frame_cnt--;
ret = -1;
@@ -2848,11 +2832,26 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
if (!devp)
return IRQ_HANDLED;
devp->irq_cnt++;
if (vdin_isr_monitor & VDIN_ISR_MONITOR_VF)
pr_info("vdin frame_cnt:%d vdin_cur_time:%lld\n",
devp->frame_cnt, ktime_to_us(ktime_get()));
vdin_check_cycle(devp);
if (vdin_check_cycle(devp)) {
vdin_drop_frame_info(devp, "cycle error");
vdin_pause_hw_write(devp, 0);
return IRQ_HANDLED;
}
/* debug interrupt interval time
*
* this code about system time must be outside of spinlock.
* because the spinlock may affect the system time.
*/
if (vdin_vs_duration_check(devp) < 0) {
vdin_drop_frame_info(devp, "duration error");
vdin_pause_hw_write(devp, 0);
return IRQ_HANDLED;
}
if (!devp->frontend) {
devp->vdin_irq_flag = VDIN_IRQ_FLG_NO_END;
@@ -2941,16 +2940,6 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
offset = devp->addr_offset;
vdin_set_mif_on_off(devp, devp->flags & VDIN_FLAG_RDMA_ENABLE);
isr_log(devp->vfp);
devp->irq_cnt++;
/* debug interrupt interval time
*
* this code about system time must be outside of spinlock.
* because the spinlock may affect the system time.
*/
if (vdin_vs_duration_check(devp) < 0) {
vdin_drop_frame_info(devp, "duration error");
return IRQ_HANDLED;
}
/* 10 is prevent abnormal frame */
if (devp->starting_chg && devp->irq_cnt < 10) {
@@ -3284,9 +3273,13 @@ irqreturn_t vdin_isr(int irq, void *dev_id)
if (((devp->game_mode & VDIN_GAME_MODE_2) && frame_lock_type_vrr_lock()) &&
devp->dbg_force_one_buffer) {
next_wr_vfe = devp->curr_wr_vfe;
if (next_wr_vfe)
next_wr_vfe->flag |= VF_FLAG_ONE_BUFFER_MODE;
} else {
/* prepare for next input data */
next_wr_vfe = provider_vf_get(devp->vfp);
if (next_wr_vfe)
next_wr_vfe->flag &= (~VF_FLAG_ONE_BUFFER_MODE);
}
if (!next_wr_vfe) {
devp->vdin_irq_flag = VDIN_IRQ_FLG_NO_NEXT_FE;
@@ -4037,6 +4030,22 @@ static int vdin_release(struct inode *inode, struct file *file)
return 0;
}
static int vdin_cmd_check(struct vdin_dev_s *devp, unsigned int cmd)
{
if (devp->work_mode == VDIN_WORK_MD_V4L &&
(devp->vdin_function_sel & VDIN_V4L2_IOCTL_CHK) &&
!(cmd == TVIN_IOC_G_PARM ||
cmd == TVIN_IOC_G_SIG_INFO ||
cmd == TVIN_IOC_G_FRONTEND_INFO ||
cmd == TVIN_IOC_G_BUF_INFO ||
cmd == TVIN_IOC_GET_COLOR_RANGE ||
cmd == TVIN_IOC_G_INPUT_TIMING ||
cmd == TVIN_IOC_G_EVENT_INFO))
return -EBUSY;
return 0;
}
/* vdin ioctl cmd:
* TVIN_IOC_OPEN /TVIN_IOC_CLOSE
* TVIN_IOC_START_DEC /TVIN_IOC_STOP_DEC
@@ -4086,6 +4095,12 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
return 0;
}
if (vdin_cmd_check(devp, cmd)) {
pr_warn("vdin%d,do not support cmd:%#x on v4l mode\n",
devp->index, cmd);
return -EBUSY;
}
if (vdin_dbg_en & VDIN_DBG_CNTL_IOCTL)
pr_info("vdin%d cmd:0x%x come in\n",
devp->index, cmd);
@@ -4136,6 +4151,14 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
enum tvin_sig_fmt_e fmt;
mutex_lock(&devp->fe_lock);
if (copy_from_user(&parm, argp, sizeof(struct tvin_parm_s))) {
pr_err("TVIN_IOC_START_DEC(%d) invalid parameter\n",
devp->index);
ret = -EFAULT;
mutex_unlock(&devp->fe_lock);
break;
}
if (devp->flags & VDIN_FLAG_DEC_STARTED) {
pr_err("TVIN_IOC_START_DEC(%d) port 0x%x, started already flags=0x%x\n",
parm.index, parm.port, devp->flags);
@@ -4150,8 +4173,9 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
if ((devp->parm.info.status != TVIN_SIG_STATUS_STABLE ||
devp->parm.info.fmt == TVIN_SIG_FMT_NULL) &&
!IS_TVAFE_ATV_SRC(devp->parm.port)) {
pr_err("TVIN_IOC_START_DEC: port %s start invalid\n",
tvin_port_str(devp->parm.port));
pr_err("TVIN_IOC_START_DEC: port %s fmt:%s,start invalid\n",
tvin_port_str(devp->parm.port),
tvin_sig_fmt_str(parm.info.fmt));
pr_err(" status: %s, fmt: %s\n",
tvin_sig_status_str(devp->parm.info.status),
tvin_sig_fmt_str(devp->parm.info.fmt));
@@ -4159,18 +4183,17 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
mutex_unlock(&devp->fe_lock);
break;
}
if (copy_from_user(&parm, argp, sizeof(struct tvin_parm_s))) {
pr_err("TVIN_IOC_START_DEC(%d) invalid parameter\n",
devp->index);
ret = -EFAULT;
mutex_unlock(&devp->fe_lock);
break;
}
if (parm.info.fmt == TVIN_SIG_FMT_NULL &&
IS_TVAFE_ATV_SRC(devp->parm.port)) {
de_fmt_flag = 1;
devp->parm.info.fmt = TVIN_SIG_FMT_CVBS_NTSC_M;
fmt = devp->parm.info.fmt;
if (parm.info.fmt == TVIN_SIG_FMT_NULL) {
if (IS_TVAFE_ATV_SRC(devp->parm.port)) {
de_fmt_flag = 1;
devp->parm.info.fmt = TVIN_SIG_FMT_CVBS_NTSC_M;
fmt = devp->parm.info.fmt;
} else {
pr_err("port:%s,fmt null\n", tvin_port_str(devp->parm.port));
ret = -EFAULT;
mutex_unlock(&devp->fe_lock);
break;
}
} else {
de_fmt_flag = 0;
devp->parm.info.fmt = parm.info.fmt;
@@ -4358,8 +4381,8 @@ 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\n",
__func__, info.signal_type, info.status, info.fps);
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);
mutex_unlock(&devp->fe_lock);
break;
}
@@ -4537,12 +4560,14 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
case TVIN_IOC_G_VRR_STATUS:
if (vdin_check_is_spd_data(devp) &&
(devp->prop.spd_data.data[5] >> 2 & 0x3))
(devp->vrr_data.cur_spd_data5 >> 2 & 0x3)) {
vdin_vrr_status.cur_vrr_status =
((devp->prop.spd_data.data[5] >> 2 & 0x3) + 1);
else
((devp->vrr_data.cur_spd_data5 >> 2 & 0x3) + 1);
} else {
vdin_vrr_status.cur_vrr_status =
devp->prop.vtem_data.vrr_en;
devp->vrr_data.cur_spd_data5 = 0;
}
vdin_vrr_status.local_dimming_disable = 1;
vdin_vrr_status.native_color_en = 0;
@@ -4555,14 +4580,15 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
}
if (vdin_dbg_en)
pr_info("TVIN_IOC_G_VRR_STATUS,VrrSta:%d LD_dis:%d NC_en:%d TM_en:%d vrr:%d %d %d\n",
pr_info("VrrSta:%d LD_dis:%d NC_en:%d TM_en:%d vrr:%d %d %d %d\n",
vdin_vrr_status.cur_vrr_status,
vdin_vrr_status.local_dimming_disable,
vdin_vrr_status.native_color_en,
vdin_vrr_status.tone_mapping_en,
devp->prop.vtem_data.vrr_en,
devp->prop.spd_data.data[0],
devp->prop.spd_data.data[5]);
devp->prop.spd_data.data[5],
devp->vrr_data.cur_spd_data5);
break;
case TVIN_IOC_GET_COLOR_RANGE:
if (copy_to_user(argp, &color_range_force,
@@ -4842,6 +4868,9 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
ret = -EFAULT;
break;
}
if (vdin_dbg_en)
pr_err("Enter,TVIN_IOC_S_PC_MODE:%d tmp:%d func_sel:0x%x\n",
vdin_pc_mode, tmp, devp->vdin_function_sel);
mutex_lock(&devp->fe_lock);
if (vdin_pc_mode != tmp &&
@@ -4863,8 +4892,7 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
mutex_unlock(&devp->fe_lock);
if (vdin_dbg_en)
pr_info("TVIN_IOC_S_PC_MODE:%d tmp:%d func_sel:0x%x\n",
vdin_pc_mode, tmp, devp->vdin_function_sel);
pr_info("TVIN_IOC_S_PC_MODE done.vdin_pc_mode:%d\n", vdin_pc_mode);
break;
case TVIN_IOC_S_FRAME_WR_EN:
if (copy_from_user(&devp->vframe_wr_en, argp,
+7 -1
View File
@@ -146,7 +146,8 @@
/* 20230527: fix screencap abnormal under display 4k120 on t3x */
/* 20230529: bringup for txhd2 */
/* 20230608: vdin not clear ratio_control value */
#define VDIN_VER "20230608"
#define VDIN_VER "2023/06/24"
//#define T3X_PXP_BRINGUP
//#define VDIN_BRINGUP_NO_VF
@@ -312,6 +313,7 @@ struct match_data_s {
/* #define VDIN_DEBUG */
/* vdin_function_sel control bits start */
#define VDIN_SELF_STOP_START BIT(0)
#define VDIN_V4L2_IOCTL_CHK BIT(1)
#define VDIN_VADJ1_TO_VD1 BIT(3)
#define VDIN_ADJUST_VLOCK BIT(4)
#define VDIN_PROP_RX_UPDATE BIT(5)
@@ -674,6 +676,10 @@ struct vdin_vrr_s {
unsigned int vrr_mode;
/* vrr_en in frame_lock_policy */
bool frame_lock_vrr_en;
/* vrr states may changed only once and recovery quickly
* app may get wrong state if from prop.spd_data[5]
*/
u8 cur_spd_data5;
};
/* scatter start */
+6 -2
View File
@@ -728,7 +728,8 @@ void tvin_sig_chg_event_process(struct vdin_dev_s *devp, u32 chg)
}
if (devp->starting_chg) {
pr_info("starting_chg send event:0X%x\n", devp->starting_chg);
pr_info("starting_chg send event:0X%x;dv[%d,%d]\n",
devp->starting_chg, devp->dv.dv_flag, devp->prop.dolby_vision);
chg = devp->starting_chg;
devp->starting_chg = 0;
}
@@ -760,13 +761,16 @@ void tvin_sig_chg_event_process(struct vdin_dev_s *devp, u32 chg)
devp->event_info.event_sts = TVIN_SIG_CHG_AFD;
} else if (chg & TVIN_SIG_CHG_VRR) {
devp->event_info.event_sts = TVIN_SIG_CHG_VRR;
pr_info("%s vrr chg:(%d->%d) spd:(%d->%d),vic:%d,fr:%d\n", __func__,
pr_info("%s vrr chg:(%d->%d) spd:(%d->%d)%d,vic:%d,fr:%d\n", __func__,
devp->vrr_data.vdin_vrr_en_flag,
devp->prop.vtem_data.vrr_en,
devp->pre_prop.spd_data.data[5],
devp->prop.spd_data.data[5],
devp->vrr_data.cur_spd_data5,
devp->prop.hw_vic,
devp->prop.vtem_data.base_framerate);
devp->vrr_data.cur_spd_data5 = devp->prop.spd_data.data[5];
devp->pre_prop.spd_data.data[5] = devp->prop.spd_data.data[5];
devp->pre_prop.vtem_data.vrr_en =
devp->prop.vtem_data.vrr_en;
devp->vrr_data.vdin_vrr_en_flag =
+13 -10
View File
@@ -426,8 +426,8 @@ static int vdin_vidioc_enum_input(struct file *file,
inp->std = V4L2_STD_ALL;
str = tvin_port_str(devp->v4l2_port[inp->index]);
if (str && (strlen(str) < sizeof(inp->name)))
strcpy(inp->name, tvin_port_str(devp->v4l2_port[inp->index]));
if (str)
strscpy(inp->name, str, sizeof(inp->name));
dprintk(1, "%s,port[%d]:%s\n", __func__, inp->index, inp->name);
return 0;
@@ -1234,6 +1234,9 @@ static int vdin_vidioc_s_input(struct file *file, void *priv, unsigned int i)
devp->v4l2_port_cur = devp->v4l2_port[i];
devp->unstable_flag = false;
devp->work_mode = VDIN_WORK_MD_V4L;
devp->afbce_flag = 0;
if (devp->index == 0 && !(devp->flags & VDIN_FLAG_DEC_OPENED)) {
ret = vdin_open_fe(devp->parm.port, 0, devp);
if (ret) {
@@ -1419,16 +1422,10 @@ static int vdin_v4l2_open(struct file *file)
dprintk(0, "%s error VDIN_FLAG_DEC_STARTED\n", __func__);
return -EPERM;
}
devp->work_mode = VDIN_WORK_MD_V4L;
// if (devp->work_mode != VDIN_WORK_MD_V4L) {
// dprintk(0, "%s err:vdin v4l mode not enabled\n", __func__);
// return -EPERM;
// }
devp->afbce_flag_backup = devp->afbce_flag;
devp->afbce_flag = 0;
dprintk(0, "%s\n", __func__);
/*dump_stack();*/
devp->afbce_flag_backup = devp->afbce_flag;
v4l2_fh_open(file);
@@ -1449,6 +1446,11 @@ static int vdin_v4l2_release(struct file *file)
if (IS_ERR_OR_NULL(devp))
return -EFAULT;
if (devp->flags & VDIN_FLAG_DEC_STARTED) {
dprintk(0, "%s error VDIN_FLAG_DEC_STARTED\n", __func__);
return -EPERM;
}
/*release que*/
ret = vb2_fop_release(file);
@@ -1467,8 +1469,9 @@ static int vdin_v4l2_release(struct file *file)
}
}
memset(devp->st_vdin_set_canvas_addr, 0, sizeof(devp->st_vdin_set_canvas_addr));
devp->afbce_flag = devp->afbce_flag_backup;
}
devp->afbce_flag = devp->afbce_flag_backup;
devp->work_mode = VDIN_WORK_MD_NORMAL;
return ret;
+2
View File
@@ -40,6 +40,8 @@
#define VF_FLAG_NORMAL_FRAME 0x00000001
#define VF_FLAG_FREEZED_FRAME 0x00000002
#define VF_FLAG_ONE_BUFFER_MODE 0x00000004
#define VFRAME_DISP_MAX_NUM 25
#define VDIN_CANVAS_MIN_CNT 3
#define VDIN_CANVAS_MAX_CNT 12