On Tue, May 21, 2013 at 1:08 AM, Inki Dae <inki.dae@xxxxxxxxxxx> wrote: > This patch fixes the issue that drm_vblank_get() is failed. > > The issus occurs when next page flip request is tried > if previous page flip event wasn't completed yet and then > dpms became off. > > So this patch make sure that page flip event is completed > before dpms goes to off. Hi, This patch is a squash of the two following patches from the Chrome OS tree with the KDS bits removed and the dpms off bit added: http://git.chromium.org/gitweb/?p=chromiumos/third_party/kernel-next.git;a=commitdiff;h=2e77cd4e423967862ca01b1af82aa8b5b7429fc4;hp=aba002da4c6e5efec4d43e1ce33930a79269349a http://git.chromium.org/gitweb/?p=chromiumos/third_party/kernel-next.git;a=commitdiff;h=b4ec8bfa750ef43a43c2da746c8afdbb51002882;hp=4f28b9a75c928f229443d7c6c3163159ceb6903a Please keep proper attribution. > > Signed-off-by: Inki Dae <inki.dae@xxxxxxxxxxx> > Signed-off-by: Kyungmin Park <kyungmin.park@xxxxxxxxxxx> > --- > drivers/gpu/drm/exynos/exynos_drm_crtc.c | 16 ++++++++++++++++ > 1 files changed, 16 insertions(+), 0 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c > index e8894bc..69a77e9 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c > @@ -48,6 +48,8 @@ struct exynos_drm_crtc { > unsigned int pipe; > unsigned int dpms; > enum exynos_crtc_mode mode; > + wait_queue_head_t pending_flip_queue; > + atomic_t pending_flip; > }; > > static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) > @@ -61,6 +63,13 @@ static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode) > return; > } > > + if (mode > DRM_MODE_DPMS_ON) { > + /* wait for the completion of page flip. */ > + wait_event(exynos_crtc->pending_flip_queue, > + atomic_read(&exynos_crtc->pending_flip) == 0); > + drm_vblank_off(crtc->dev, exynos_crtc->pipe); You should be using vblank_put/get. Stéphane > + } > + > exynos_drm_fn_encoder(crtc, &mode, exynos_drm_encoder_crtc_dpms); > exynos_crtc->dpms = mode; > } > @@ -225,6 +234,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, > spin_lock_irq(&dev->event_lock); > list_add_tail(&event->base.link, > &dev_priv->pageflip_event_list); > + atomic_set(&exynos_crtc->pending_flip, 1); > spin_unlock_irq(&dev->event_lock); > > crtc->fb = fb; > @@ -344,6 +354,8 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr) > > exynos_crtc->pipe = nr; > exynos_crtc->dpms = DRM_MODE_DPMS_OFF; > + init_waitqueue_head(&exynos_crtc->pending_flip_queue); > + atomic_set(&exynos_crtc->pending_flip, 0); > exynos_crtc->plane = exynos_plane_init(dev, 1 << nr, true); > if (!exynos_crtc->plane) { > kfree(exynos_crtc); > @@ -398,6 +410,8 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc) > { > struct exynos_drm_private *dev_priv = dev->dev_private; > struct drm_pending_vblank_event *e, *t; > + struct drm_crtc *drm_crtc = dev_priv->crtc[crtc]; > + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(drm_crtc); > struct timeval now; > unsigned long flags; > > @@ -419,6 +433,8 @@ void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int crtc) > list_move_tail(&e->base.link, &e->base.file_priv->event_list); > wake_up_interruptible(&e->base.file_priv->event_wait); > drm_vblank_put(dev, crtc); > + atomic_set(&exynos_crtc->pending_flip, 0); > + wake_up(&exynos_crtc->pending_flip_queue); > } > > spin_unlock_irqrestore(&dev->event_lock, flags); > -- > 1.7.5.4 > > _______________________________________________ > dri-devel mailing list > dri-devel@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/dri-devel _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel