diff --git a/drivers/media/vin/tvin/vdin/vdin_ctl.c b/drivers/media/vin/tvin/vdin/vdin_ctl.c index 3e3b77ee9..c2c8da470 100644 --- a/drivers/media/vin/tvin/vdin/vdin_ctl.c +++ b/drivers/media/vin/tvin/vdin/vdin_ctl.c @@ -6501,26 +6501,35 @@ bool vdin_check_is_spd_data(struct vdin_dev_s *devp) return false; } +bool vdin_is_freesync_head(struct tvin_spd_data_s *spd_data) +{ + if (!spd_data) + return false; + + if (spd_data->data[0] == 0x1A && + spd_data->data[1] == 0x00 && + spd_data->data[2] == 0x00) + return true; + else + return false; +} + bool vdin_check_spd_data_chg(struct vdin_dev_s *devp) { if (!devp) return false; - if ((devp->pre_prop.spd_data.data[0] == 0x1a && - devp->pre_prop.spd_data.data[1] == 0x00 && - devp->pre_prop.spd_data.data[2] == 0x00) || - (devp->prop.spd_data.data[0] == 0x1a && - devp->prop.spd_data.data[1] == 0x00 && - devp->prop.spd_data.data[2] == 0x00)) { + if (vdin_is_freesync_head(&devp->prop.spd_data) || + vdin_is_freesync_head(&devp->pre_prop.spd_data)) { /* 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->vrr_data.cur_spd_data5 >> 2 & 0x3)) { + (devp->prop.spd_data.data[5] >> 2 & 0x3)) { return true; } + if (devp->vrr_data.cur_vrr_status != devp->vrr_data.pre_vrr_status) + return true; } else { return false; } @@ -7523,11 +7532,10 @@ enum vdin_vrr_mode_e get_cur_vrr_status(struct vdin_dev_s *devp) sync_duration_val = vinfo->sync_duration_num / vinfo->sync_duration_den; } - freesync_type = devp->vrr_data.cur_spd_data5 >> 2 & 0x3; + freesync_type = devp->pre_prop.spd_data.data[5] >> 2 & 0x3; if (devp->prop.vtem_data.vrr_en) { - devp->vrr_data.cur_spd_data5 = 0; ret = VDIN_VRR_BASIC; - } else if (vdin_check_is_spd_data(devp) && freesync_type) { + } else if (vdin_is_freesync_head(&devp->pre_prop.spd_data) && freesync_type) { if ((freesync_type == 1 || freesync_type == 2) && sync_duration_val < 120) ret = VDIN_VRR_FREESYNC; @@ -7536,6 +7544,8 @@ enum vdin_vrr_mode_e get_cur_vrr_status(struct vdin_dev_s *devp) ret = VDIN_VRR_FREESYNC_PREMIUM; else if (freesync_type == 3) ret = VDIN_VRR_FREESYNC_PREMIUM_PRO; + else + ret = VDIN_VRR_FREESYNC; } else { ret = VDIN_VRR_OFF; } diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.c b/drivers/media/vin/tvin/vdin/vdin_drv.c index 9284ddb89..72b0f4e48 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.c +++ b/drivers/media/vin/tvin/vdin/vdin_drv.c @@ -1353,7 +1353,6 @@ 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; devp->vdin_drop_cnt = 0; @@ -2736,7 +2735,7 @@ int vdin_vframe_put_and_recycle(struct vdin_dev_s *devp, struct vf_entry *vfe, 1000)); if (vdin_isr_monitor & VDIN_ISR_MONITOR_VF) - pr_info("vdin%d cnt:%d vf:%d sg_type:%#x type:%#x flag:%u dur:%u disp:%d\n", + pr_info("vdin%d cnt:%d vf:%d sg_type:%#x type:%#x flag:%#x dur:%u disp:%d\n", devp->index, devp->irq_cnt, devp->vfp->last_last_vfe->vf.index, devp->vfp->last_last_vfe->vf.signal_type, @@ -4777,6 +4776,8 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) sizeof(struct vdin_vrr_freesync_param_s))) { pr_info("vdin_vrr_status copy fail\n"); ret = -EFAULT; + } else { + devp->vrr_data.cur_vrr_status = vdin_vrr_status.cur_vrr_status; } if (vdin_dbg_en) @@ -4788,7 +4789,7 @@ static long vdin_ioctl(struct file *file, unsigned int cmd, unsigned long arg) devp->prop.vtem_data.vrr_en, devp->prop.spd_data.data[0], devp->prop.spd_data.data[5], - devp->vrr_data.cur_spd_data5); + devp->pre_prop.spd_data.data[5]); break; case TVIN_IOC_GET_COLOR_RANGE: if (copy_to_user(argp, &color_range_force, @@ -6094,8 +6095,10 @@ static int vdin_get_vinfo_notify_callback(struct notifier_block *block, return 0; devp->vinfo_std_duration = vinfo->sync_duration_num / vinfo->sync_duration_den; + devp->vrr_data.cur_vrr_status = get_cur_vrr_status(devp); if (vdin_dbg_en) - pr_info("vdin%d,std_dur:%d\n", devp->index, devp->vinfo_std_duration); + pr_info("vdin%d,std_dur:%d,vrr:%d\n", devp->index, devp->vinfo_std_duration, + devp->vrr_data.cur_vrr_status); if (devp_vdin1 && devp->dtdata->hw_ver == VDIN_HW_T3X) devp_vdin1->vinfo_std_duration = devp->vinfo_std_duration; diff --git a/drivers/media/vin/tvin/vdin/vdin_drv.h b/drivers/media/vin/tvin/vdin/vdin_drv.h index 2a90a4ae2..bacf7dbe6 100644 --- a/drivers/media/vin/tvin/vdin/vdin_drv.h +++ b/drivers/media/vin/tvin/vdin/vdin_drv.h @@ -737,10 +737,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; + /* app get this status */ + enum vdin_vrr_mode_e pre_vrr_status; + /* driver detect status */ + enum vdin_vrr_mode_e cur_vrr_status; }; /* scatter start */ diff --git a/drivers/media/vin/tvin/vdin/vdin_sm.c b/drivers/media/vin/tvin/vdin/vdin_sm.c index 1c66f8f39..f6e11b6fe 100644 --- a/drivers/media/vin/tvin/vdin/vdin_sm.c +++ b/drivers/media/vin/tvin/vdin/vdin_sm.c @@ -195,6 +195,8 @@ enum tvin_color_fmt_range_e void vdin_update_prop(struct vdin_dev_s *devp) { /*devp->pre_prop.fps = devp->prop.fps;*/ + devp->vrr_data.cur_vrr_status = get_cur_vrr_status(devp); + devp->vrr_data.pre_vrr_status = devp->vrr_data.cur_vrr_status; devp->dv.dv_flag = devp->prop.dolby_vision; devp->dv.low_latency = devp->prop.low_latency; /*devp->pre_prop.latency.allm_mode = devp->prop.latency.allm_mode;*/ @@ -439,7 +441,6 @@ static enum tvin_sg_chg_flg vdin_hdmirx_fmt_chg_detect(struct vdin_dev_s *devp) devp->prop.spd_data.data[5], devp->pre_prop.spd_data.data[0], devp->prop.spd_data.data[0]); - devp->pre_prop.spd_data.data[5] = devp->prop.spd_data.data[5]; } } else { devp->vrr_data.vrr_chg_cnt = 0; @@ -754,16 +755,17 @@ 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)%d,vic:%d,fr:%d\n", __func__, + pr_info("%s vrr chg:(%d->%d) spd:(%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]; + memcpy(&devp->pre_prop.spd_data, &devp->prop.spd_data, + sizeof(devp->prop.spd_data)); + devp->vrr_data.cur_vrr_status = get_cur_vrr_status(devp); + devp->vrr_data.pre_vrr_status = devp->vrr_data.cur_vrr_status; devp->pre_prop.vtem_data.vrr_en = devp->prop.vtem_data.vrr_en; devp->vrr_data.vdin_vrr_en_flag =