All of lore.kernel.org
 help / color / mirror / Atom feed
From: ville.syrjala@linux.intel.com
To: dri-devel@lists.freedesktop.org
Cc: intel-gfx@lists.freedesktop.org
Subject: [PATCH 05/13] drm/i915: Make a copy of the calculated plane regs
Date: Fri, 16 Nov 2012 16:22:17 +0200	[thread overview]
Message-ID: <1353075745-30115-6-git-send-email-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <1353075745-30115-1-git-send-email-ville.syrjala@linux.intel.com>

From: Ville Syrjälä <ville.syrjala@linux.intel.com>

The register values are computed when the flip ioctl is issued, and
they're used only after we've waited for the GPU to finish rendering.
The computed values are store in the intel_crtc and intel_plane structs,
so issuing another flip before the previous one has been fully completed
would clobber those stored registers. Fix the problem by making a copy
of the calculated register values inside the intel_flip structure. The
copy is then used when it's time to commit the registers to the hardware.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    4 +++-
 drivers/gpu/drm/i915/intel_atomic.c  |    8 ++++++--
 drivers/gpu/drm/i915/intel_display.c |   14 ++++++++------
 drivers/gpu/drm/i915/intel_drv.h     |    2 +-
 drivers/gpu/drm/i915/intel_sprite.c  |   24 ++++++++++++------------
 5 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 8aaf0ce..91e2dc6 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -247,6 +247,8 @@ struct drm_i915_error_state {
 	struct intel_display_error_state *display;
 };
 
+struct intel_plane_regs;
+
 struct drm_i915_display_funcs {
 	bool (*fbc_enabled)(struct drm_device *dev);
 	void (*enable_fbc)(struct drm_crtc *crtc, unsigned long interval);
@@ -278,7 +280,7 @@ struct drm_i915_display_funcs {
 			    int x, int y);
 	int (*calc_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 			  int x, int y);
-	void (*commit_plane)(struct drm_crtc *crtc);
+	void (*commit_plane)(struct drm_crtc *crtc, const struct intel_plane_regs *regs);
 	/* clock updates for mode set */
 	/* cursor updates */
 	/* render clock increase/decrease */
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 7a0e315..0aa8c93 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -49,6 +49,8 @@ struct intel_flip {
 	struct intel_ring_buffer *ring;
 	u32 seqno;
 	unsigned int flip_seq;
+	/* FIXME need cursor regs too */
+	struct intel_plane_regs regs;
 };
 
 struct intel_plane_state {
@@ -1988,11 +1990,11 @@ static bool intel_flip_flip(struct drm_flip *flip,
 		struct drm_plane *plane = intel_flip->plane;
 		struct intel_plane *intel_plane = to_intel_plane(plane);
 
-		intel_plane->commit(plane);
+		intel_plane->commit(plane, &intel_flip->regs);
 	} else {
 		struct drm_i915_private *dev_priv = dev->dev_private;
 
-		dev_priv->display.commit_plane(crtc);
+		dev_priv->display.commit_plane(crtc, &intel_flip->regs);
 	}
 
 	if (intel_flip->has_cursor)
@@ -2339,6 +2341,7 @@ static void atomic_pipe_commit(struct drm_device *dev,
 		/* should already be checked so can't fail */
 		/* FIXME refactor the failing parts? */
 		dev_priv->display.calc_plane(crtc, crtc->fb, crtc->x, crtc->y);
+		intel_flip->regs = intel_crtc->primary_regs;
 
 		if (st->cursor_dirty) {
 			intel_flip->has_cursor = true;
@@ -2405,6 +2408,7 @@ static void atomic_pipe_commit(struct drm_device *dev,
 		}
 
 		intel_plane->calc(plane, plane->fb, &st->coords);
+		intel_flip->regs = intel_plane->regs;
 
 		if (st->old.fb)
 			intel_flip->old_fb_id = st->old.fb->base.id;
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7537a2c..48eeed5 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2030,13 +2030,13 @@ unsigned long intel_gen4_compute_offset_xtiled(int *x, int *y,
 	return tile_rows * pitch * 8 + tiles * 4096;
 }
 
-static void intel_commit_plane(struct drm_crtc *crtc)
+static void intel_commit_plane(struct drm_crtc *crtc,
+			       const struct intel_plane_regs *regs)
 {
 	struct drm_device *dev = crtc->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int plane = intel_crtc->plane;
-	const struct intel_plane_regs *regs = &intel_crtc->primary_regs;
 
 	I915_WRITE(DSPCNTR(plane), regs->cntr);
 	I915_WRITE(DSPSTRIDE(plane), regs->stride);
@@ -2153,15 +2153,16 @@ static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
 			     int x, int y)
 {
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int ret;
 
 	ret = i9xx_calc_plane(crtc, fb, x, y);
 	if (ret)
 		return ret;
 
-	intel_commit_plane(crtc);
+	intel_commit_plane(crtc, &intel_crtc->primary_regs);
 
-	POSTING_READ(DSPCNTR(to_intel_crtc(crtc)->plane));
+	POSTING_READ(DSPCNTR(intel_crtc->plane));
 
 	return 0;
 }
@@ -2257,15 +2258,16 @@ static int ironlake_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *
 				 int x, int y)
 {
 	struct drm_i915_private *dev_priv = crtc->dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	int ret;
 
 	ret = ironlake_calc_plane(crtc, fb, x, y);
 	if (ret)
 		return ret;
 
-	intel_commit_plane(crtc);
+	intel_commit_plane(crtc, &intel_crtc->primary_regs);
 
-	POSTING_READ(DSPCNTR(to_intel_crtc(crtc)->plane));
+	POSTING_READ(DSPCNTR(intel_crtc->plane));
 
 	return 0;
 }
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 617ba4d..9771a10 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -274,7 +274,7 @@ struct intel_plane {
 	void (*calc)(struct drm_plane *plane, struct drm_framebuffer *fb,
 		     const struct intel_plane_coords *clip);
 	void (*prepare)(struct drm_plane *plane);
-	void (*commit)(struct drm_plane *plane);
+	void (*commit)(struct drm_plane *plane, const struct intel_plane_regs *regs);
 	struct intel_plane_regs regs;
 	struct drm_flip_helper flip_helper;
 };
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index ce3b950..d960e19 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -300,13 +300,13 @@ ivb_calc_plane(struct drm_plane *plane,
 }
 
 static void
-ivb_commit_plane(struct drm_plane *plane)
+ivb_commit_plane(struct drm_plane *plane,
+		 const struct intel_plane_regs *regs)
 {
 	struct drm_device *dev = plane->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	int pipe = intel_plane->pipe;
-	const struct intel_plane_regs *regs = &intel_plane->regs;
 
 	I915_WRITE(SPRKEYVAL(pipe), regs->keyval);
 	I915_WRITE(SPRKEYMAX(pipe), regs->keymaxval);
@@ -371,7 +371,7 @@ ivb_update_plane(struct drm_plane *plane,
 
 	ivb_calc_plane(plane, fb, coords);
 	ivb_prepare_plane(plane);
-	ivb_commit_plane(plane);
+	ivb_commit_plane(plane, &intel_plane->regs);
 	POSTING_READ(SPRSURF(pipe));
 }
 
@@ -387,7 +387,7 @@ ivb_disable_plane(struct drm_plane *plane)
 	regs->cntr &= ~SPRITE_ENABLE;
 	/* Can't leave the scaler enabled... */
 	regs->scale = 0;
-	ivb_commit_plane(plane);
+	ivb_commit_plane(plane, regs);
 	POSTING_READ(SPRSURF(pipe));
 
 	dev_priv->sprite_scaling_enabled &= ~(1 << pipe);
@@ -413,7 +413,7 @@ ivb_update_colorkey(struct drm_plane *plane,
 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
 		regs->cntr |= SPRITE_SOURCE_KEY;
 
-	ivb_commit_plane(plane);
+	ivb_commit_plane(plane, regs);
 	POSTING_READ(SPRKEYMSK(intel_plane->pipe));
 
 	return 0;
@@ -546,13 +546,13 @@ ilk_prepare_plane(struct drm_plane *plane)
 }
 
 static void
-ilk_commit_plane(struct drm_plane *plane)
+ilk_commit_plane(struct drm_plane *plane,
+		 const struct intel_plane_regs *regs)
 {
 	struct drm_device *dev = plane->dev;
 	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 	int pipe = intel_plane->pipe;
-	const struct intel_plane_regs *regs = &intel_plane->regs;
 
 	I915_WRITE(DVSKEYVAL(pipe), regs->keyval);
 	I915_WRITE(DVSKEYMAX(pipe), regs->keymaxval);
@@ -579,7 +579,7 @@ ilk_update_plane(struct drm_plane *plane,
 
 	ilk_calc_plane(plane, fb, coords);
 	ilk_prepare_plane(plane);
-	ilk_commit_plane(plane);
+	ilk_commit_plane(plane, &intel_plane->regs);
 	POSTING_READ(DVSSURF(pipe));
 }
 
@@ -595,7 +595,7 @@ ilk_disable_plane(struct drm_plane *plane)
 	regs->cntr &= ~DVS_ENABLE;
 	/* Disable the scaler */
 	regs->scale = 0;
-	ilk_commit_plane(plane);
+	ilk_commit_plane(plane, regs);
 	POSTING_READ(DVSSURF(pipe));
 }
 
@@ -627,7 +627,7 @@ intel_enable_primary(struct drm_crtc *crtc)
 	intel_update_fbc(dev);
 
 	regs->cntr = I915_READ(reg) | DISPLAY_PLANE_ENABLE;
-	dev_priv->display.commit_plane(crtc);
+	dev_priv->display.commit_plane(crtc, regs);
 }
 
 void
@@ -643,7 +643,7 @@ intel_disable_primary(struct drm_crtc *crtc)
 		return;
 
 	regs->cntr = I915_READ(reg) & ~DISPLAY_PLANE_ENABLE;
-	dev_priv->display.commit_plane(crtc);
+	dev_priv->display.commit_plane(crtc, regs);
 
 	intel_crtc->primary_disabled = true;
 	intel_update_fbc(dev);
@@ -668,7 +668,7 @@ ilk_update_colorkey(struct drm_plane *plane,
 	else if (key->flags & I915_SET_COLORKEY_SOURCE)
 		regs->cntr |= DVS_SOURCE_KEY;
 
-	ilk_commit_plane(plane);
+	ilk_commit_plane(plane, regs);
 	POSTING_READ(DVSKEYMSK(intel_plane->pipe));
 
 	return 0;
-- 
1.7.8.6

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

  parent reply	other threads:[~2012-11-16 14:22 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-16 14:22 [PATCH 00/13] drm/i915: Non-blocking GPU synchronization for atomic page flips (v2) ville.syrjala
2012-11-16 14:22 ` [PATCH 01/13] drm/i915: Unstatic i915_gem_check_olr() ville.syrjala
2012-11-16 14:22 ` [PATCH 02/13] drm/i915: Refactor atomic flip code ville.syrjala
2012-11-16 14:22 ` [PATCH 03/13] drm/i915: Implement a non-blocking GPU synchronization mechanism for atomic page flips ville.syrjala
2012-11-16 14:22 ` [PATCH 04/13] drm/i915: Release all atomic flips when GPU hangs ville.syrjala
2012-11-16 14:22 ` ville.syrjala [this message]
2012-11-16 14:22 ` [PATCH 06/13] drm/i915: Clear pending flips in haswell_crtc_disable() ville.syrjala
2012-11-16 14:22 ` [PATCH 07/13] drm/i915: Drop all flips waiting for the GPU when the CRTC is about to be disabled ville.syrjala
2012-11-16 14:22 ` [PATCH 08/13] drm/i915: Add pin count trace point ville.syrjala
2012-11-16 14:22 ` [PATCH 09/13] drm/i915: Add trace points for flip queue length ville.syrjala
2012-11-16 14:22 ` [PATCH 10/13] HACK: drm/i915: Make non-blocking GPU synchronization optional ville.syrjala
2012-11-16 14:22 ` [PATCH 11/13] drm/i915: Add some timing debugs to atomic flips ville.syrjala
2012-11-16 14:22 ` [PATCH 12/13] drm/i915: Add post flush DSL readout for surflive debug ville.syrjala
2012-11-16 14:22 ` [PATCH 13/13] drm/i915: Add trace point for atomic flip vblank evade ville.syrjala

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=1353075745-30115-6-git-send-email-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    /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 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.