From d58b2aac10bb21100550c2fc649501b6a29bf8f6 Mon Sep 17 00:00:00 2001 From: Zhi Zhou Date: Wed, 27 Jun 2018 15:44:45 +0800 Subject: [PATCH] video: merged from A wait AFBC idle when report state [1/1] PD#169128: [Problem] When quick switch video between 2 vsync isr, the AFBC may read wrong data, and green screen or distortion image occurs. [Solution] 1. Add delay when get video layer state, to make sure afbc is stopped 2. Remove ambiguous log print [Platform] Blanche BranchTo: NONE [Test] Change-Id: I94ccf25373f29ce188829ab1b7db6f9df1fb49ad Signed-off-by: Zhi Zhou --- drivers/amlogic/media/video_sink/video.c | 25 +++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/amlogic/media/video_sink/video.c b/drivers/amlogic/media/video_sink/video.c index 8101d774cd1f..6dceea4ca48f 100644 --- a/drivers/amlogic/media/video_sink/video.c +++ b/drivers/amlogic/media/video_sink/video.c @@ -219,6 +219,7 @@ static u32 next_peek_underflow; static DEFINE_SPINLOCK(video_onoff_lock); static int video_onoff_state = VIDEO_ENABLE_STATE_IDLE; +static u32 video_onoff_time; static DEFINE_SPINLOCK(video2_onoff_lock); static int video2_onoff_state = VIDEO_ENABLE_STATE_IDLE; static u32 hdmiin_frame_check; @@ -6291,6 +6292,7 @@ SET_FILTER: VPP_POSTBLEND_EN; video_onoff_state = VIDEO_ENABLE_STATE_IDLE; + video_onoff_time = jiffies_to_msecs(jiffies); if (debug_flag & DEBUG_FLAG_BLACKOUT) pr_info("VsyncEnableVideoLayer\n"); @@ -6306,6 +6308,7 @@ SET_FILTER: VSYNC_WR_MPEG_REG(VPP_SRSHARP0_CTRL, 0); VSYNC_WR_MPEG_REG(VPP_SRSHARP1_CTRL, 0); video_onoff_state = VIDEO_ENABLE_STATE_IDLE; + video_onoff_time = jiffies_to_msecs(jiffies); vpu_delay_work_flag |= VPU_VIDEO_LAYER1_CHANGED; if (debug_flag & DEBUG_FLAG_BLACKOUT) @@ -6349,6 +6352,7 @@ SET_FILTER: else vpp_misc_set |= (0x1ff << VPP_VD2_ALPHA_BIT); video2_onoff_state = VIDEO_ENABLE_STATE_IDLE; + video_onoff_time = jiffies_to_msecs(jiffies); if (debug_flag & DEBUG_FLAG_BLACKOUT) pr_info("VsyncEnableVideoLayer2\n"); @@ -6356,6 +6360,7 @@ SET_FILTER: vpp_misc_set &= ~(VPP_VD2_PREBLEND | VPP_VD2_POSTBLEND | VPP_PREBLEND_EN); video2_onoff_state = VIDEO_ENABLE_STATE_IDLE; + video_onoff_time = jiffies_to_msecs(jiffies); if (debug_flag & DEBUG_FLAG_BLACKOUT) pr_info("VsyncDisableVideoLayer2\n"); @@ -7600,9 +7605,23 @@ static long amvideo_ioctl(struct file *file, unsigned int cmd, ulong arg) put_user(video_global_output, (u32 __user *)argp); break; - case AMSTREAM_IOC_GET_VIDEO_LAYER1_ON: - put_user(video_onoff_state, (u32 __user *)argp); - break; + case AMSTREAM_IOC_GET_VIDEO_LAYER1_ON: { + u32 vsync_duration; + u32 video_onoff_diff = 0; + + vsync_duration = vsync_pts_inc / 90; + video_onoff_diff = + jiffies_to_msecs(jiffies) - video_onoff_time; + + if (video_onoff_state == VIDEO_ENABLE_STATE_IDLE) { + /* wait until 5ms after next vsync */ + msleep(video_onoff_diff < vsync_duration + ? vsync_duration - video_onoff_diff + 5 + : 0); + } + put_user(video_onoff_state, (u32 __user *)argp); + break; + } case AMSTREAM_IOC_SET_VIDEOPEEK: videopeek = true;