Skip to content

Commit

Permalink
[media] v4l: s5p-tv: mixer: fix handling of interlaced modes
Browse files Browse the repository at this point in the history
The next frame was fetched by Mixer at every VSYNC event.  This caused tearing
when Mixer's output in interlaced mode.  This patch fixes this bug by fetching
new frame every second VSYNC when working in interlaced mode.

Signed-off-by: Tomasz Stanislawski <t.stanislaws@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Sylwester Nawrocki <s.nawrocki@samsung.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Tomasz Stanislawski authored and Mauro Carvalho Chehab committed May 20, 2012
1 parent 2fd07a4 commit ef6a6dd
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 5 deletions.
1 change: 1 addition & 0 deletions drivers/media/video/s5p-tv/mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ struct mxr_resources {
/* event flags used */
enum mxr_devide_flags {
MXR_EVENT_VSYNC = 0,
MXR_EVENT_TOP = 1,
};

/** drivers instance */
Expand Down
15 changes: 10 additions & 5 deletions drivers/media/video/s5p-tv/mixer_reg.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,21 +296,25 @@ irqreturn_t mxr_irq_handler(int irq, void *dev_data)
/* wake up process waiting for VSYNC */
if (val & MXR_INT_STATUS_VSYNC) {
set_bit(MXR_EVENT_VSYNC, &mdev->event_flags);
/* toggle TOP field event if working in interlaced mode */
if (~mxr_read(mdev, MXR_CFG) & MXR_CFG_SCAN_PROGRASSIVE)
change_bit(MXR_EVENT_TOP, &mdev->event_flags);
wake_up(&mdev->event_queue);
}

/* clear interrupts */
if (~val & MXR_INT_EN_VSYNC) {
/* vsync interrupt use different bit for read and clear */
val &= ~MXR_INT_EN_VSYNC;
val &= ~MXR_INT_STATUS_VSYNC;
val |= MXR_INT_CLEAR_VSYNC;
}

/* clear interrupts */
mxr_write(mdev, MXR_INT_STATUS, val);

spin_unlock(&mdev->reg_slock);
/* leave on non-vsync event */
if (~val & MXR_INT_CLEAR_VSYNC)
return IRQ_HANDLED;
/* skip layer update on bottom field */
if (!test_bit(MXR_EVENT_TOP, &mdev->event_flags))
return IRQ_HANDLED;
for (i = 0; i < MXR_MAX_LAYERS; ++i)
mxr_irq_layer_handle(mdev->layer[i]);
return IRQ_HANDLED;
Expand All @@ -333,6 +337,7 @@ void mxr_reg_streamon(struct mxr_device *mdev)

/* start MIXER */
mxr_write_mask(mdev, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
set_bit(MXR_EVENT_TOP, &mdev->event_flags);

spin_unlock_irqrestore(&mdev->reg_slock, flags);
}
Expand Down

0 comments on commit ef6a6dd

Please sign in to comment.