dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Inki Dae <inki.dae@samsung.com>
To: airlied@linux.ie, dri-devel@lists.freedesktop.org
Cc: Inki Dae <inki.dae@samsung.com>,
	kyungmin.park@samsung.com, sw0312.kim@samsung.com
Subject: [PATCH 6/7] drm/exynos: fixed page flip bug.
Date: Fri, 14 Oct 2011 12:52:57 +0900	[thread overview]
Message-ID: <1318564377-8543-1-git-send-email-inki.dae@samsung.com> (raw)

in case of using two drivers such as fimd and hdmi controller that
they have their own hardware interrupt, drm framework doesn't provide
pipe number corresponding to it. so the pipe should be set to event's
from specific crtc.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
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 +++++++++++-----
 drivers/gpu/drm/exynos/exynos_drm_drv.c  |   14 ++++++++++++++
 drivers/gpu/drm/exynos/exynos_drm_drv.h  |    3 +--
 drivers/gpu/drm/exynos/exynos_drm_fimd.c |   15 +++++++++------
 4 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index 8cd9d8e..9337e5e 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -259,13 +259,21 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
 
 	mutex_lock(&dev->struct_mutex);
 
-	if (event && !dev_priv->pageflip_event) {
+	if (event) {
+		/*
+		 * the pipe from user always is 0 so we can set pipe number
+		 * of current owner to event.
+		 */
+		event->pipe = exynos_crtc->pipe;
+
 		list_add_tail(&event->base.link,
 				&dev_priv->pageflip_event_list);
 
 		ret = drm_vblank_get(dev, exynos_crtc->pipe);
 		if (ret) {
 			DRM_DEBUG("failed to acquire vblank counter\n");
+			list_del(&event->base.link);
+
 			goto out;
 		}
 
@@ -274,7 +282,7 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
 		if (ret) {
 			crtc->fb = old_fb;
 			drm_vblank_put(dev, exynos_crtc->pipe);
-			dev_priv->pageflip_event = false;
+			list_del(&event->base.link);
 
 			goto out;
 		}
@@ -282,12 +290,10 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc,
 		/*
 		 * the values related to a buffer of the drm framebuffer
 		 * to be applied should be set at here. because these values
-		 * first, is set to shadow registers and then to
+		 * first, are set to shadow registers and then to
 		 * real registers at vsync front porch period.
 		 */
 		exynos_drm_crtc_apply(crtc);
-
-		dev_priv->pageflip_event = true;
 	}
 out:
 	mutex_unlock(&dev->struct_mutex);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index a190348..83810cb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -124,6 +124,19 @@ static int exynos_drm_unload(struct drm_device *dev)
 	return 0;
 }
 
+static void exynos_drm_preclose(struct drm_device *dev,
+					struct drm_file *file_priv)
+{
+	struct exynos_drm_private *dev_priv = dev->dev_private;
+
+	/*
+	 * drm framework frees all events at release time,
+	 * so private event list should be cleared.
+	 */
+	if (!list_empty(&dev_priv->pageflip_event_list))
+		INIT_LIST_HEAD(&dev_priv->pageflip_event_list);
+}
+
 static void exynos_drm_lastclose(struct drm_device *dev)
 {
 	DRM_DEBUG_DRIVER("%s\n", __FILE__);
@@ -152,6 +165,7 @@ static struct drm_driver exynos_drm_driver = {
 				  DRIVER_MODESET | DRIVER_GEM,
 	.load			= exynos_drm_load,
 	.unload			= exynos_drm_unload,
+	.preclose		= exynos_drm_preclose,
 	.lastclose		= exynos_drm_lastclose,
 	.get_vblank_counter	= drm_vblank_count,
 	.enable_vblank		= exynos_drm_crtc_enable_vblank,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 63c1422..915f5cd 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -187,9 +187,8 @@ struct exynos_drm_manager {
 struct exynos_drm_private {
 	struct drm_fb_helper *fb_helper;
 
-	/* for pageflip */
+	/* list head for new event to be added. */
 	struct list_head pageflip_event_list;
-	bool pageflip_event;
 
 	/*
 	 * created crtc object would be contained at this array and
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index b0afa84..68446b3b 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -487,21 +487,24 @@ static struct exynos_drm_overlay_ops fimd_overlay_ops = {
 	.disable = fimd_win_disable,
 };
 
-/* for pageflip event */
 static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
 {
 	struct exynos_drm_private *dev_priv = drm_dev->dev_private;
 	struct drm_pending_vblank_event *e, *t;
 	struct timeval now;
 	unsigned long flags;
-
-	if (!dev_priv->pageflip_event)
-		return;
+	bool is_checked = false;
 
 	spin_lock_irqsave(&drm_dev->event_lock, flags);
 
 	list_for_each_entry_safe(e, t, &dev_priv->pageflip_event_list,
 			base.link) {
+		/* if event's pipe isn't same as crtc then ignore it. */
+		if (crtc != e->pipe)
+			continue;
+
+		is_checked = true;
+
 		do_gettimeofday(&now);
 		e->event.sequence = 0;
 		e->event.tv_sec = now.tv_sec;
@@ -511,8 +514,8 @@ static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc)
 		wake_up_interruptible(&e->base.file_priv->event_wait);
 	}
 
-	drm_vblank_put(drm_dev, crtc);
-	dev_priv->pageflip_event = false;
+	if (is_checked)
+		drm_vblank_put(drm_dev, crtc);
 
 	spin_unlock_irqrestore(&drm_dev->event_lock, flags);
 }
-- 
1.7.4.1

                 reply	other threads:[~2011-10-14  3:53 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1318564377-8543-1-git-send-email-inki.dae@samsung.com \
    --to=inki.dae@samsung.com \
    --cc=airlied@linux.ie \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=kyungmin.park@samsung.com \
    --cc=sw0312.kim@samsung.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox