All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drm/exynos: wait for the completion of pending page flip
@ 2013-05-21  8:08 Inki Dae
  2013-05-21 17:42 ` Stéphane Marchesin
  0 siblings, 1 reply; 10+ messages in thread
From: Inki Dae @ 2013-05-21  8:08 UTC (permalink / raw)
  To: dri-devel; +Cc: kyungmin.park, sw0312.kim

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.

Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
 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);
+	}
+
 	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

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2013-05-22  8:59 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-21  8:08 [PATCH] drm/exynos: wait for the completion of pending page flip Inki Dae
2013-05-21 17:42 ` Stéphane Marchesin
2013-05-22  4:22   ` Inki Dae
2013-05-22  4:46     ` Stéphane Marchesin
2013-05-22  6:37       ` Inki Dae
2013-05-22  6:47         ` Inki Dae
2013-05-22  8:23         ` Tomasz Figa
2013-05-22  8:41           ` Kyungmin Park
2013-05-22  8:59             ` Inki Dae
2013-05-22  8:47           ` Inki Dae

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.