All of lore.kernel.org
 help / color / mirror / Atom feed
From: ville.syrjala@linux.intel.com
To: intel-gfx@lists.freedesktop.org
Subject: [PATCH v2 08/15] drm/i915: Split cursor check_plane into i845 and i9xx variants
Date: Mon, 27 Mar 2017 21:55:39 +0300	[thread overview]
Message-ID: <20170327185546.2977-9-ville.syrjala@linux.intel.com> (raw)
In-Reply-To: <20170327185546.2977-1-ville.syrjala@linux.intel.com>

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

The 845/865 and 830/855/9xx+ style cursor don't have that
much in common with each other, so let's just split the
.check_plane() hook into two variants as well.

v2: Keep the common stuff in one place (Chris)

Cc: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> #v1
---
 drivers/gpu/drm/i915/intel_display.c | 275 ++++++++++++++++++++++-------------
 1 file changed, 171 insertions(+), 104 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index bba763b03d28..774f9668076f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9169,6 +9169,31 @@ static u32 intel_cursor_position(const struct intel_plane_state *plane_state)
 	return pos;
 }
 
+static int intel_check_cursor(struct intel_crtc_state *crtc_state,
+			      struct intel_plane_state *plane_state)
+{
+	const struct drm_framebuffer *fb = plane_state->base.fb;
+	int ret;
+
+	ret = drm_plane_helper_check_state(&plane_state->base,
+					   &plane_state->clip,
+					   DRM_PLANE_HELPER_NO_SCALING,
+					   DRM_PLANE_HELPER_NO_SCALING,
+					   true, true);
+	if (ret)
+		return ret;
+
+	if (!fb)
+		return 0;
+
+	if (fb->modifier != DRM_FORMAT_MOD_NONE) {
+		DRM_DEBUG_KMS("cursor cannot be tiled\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
 			   const struct intel_plane_state *plane_state)
 {
@@ -9194,6 +9219,68 @@ static u32 i845_cursor_ctl(const struct intel_crtc_state *crtc_state,
 		CURSOR_STRIDE(stride);
 }
 
+static bool i845_cursor_size_ok(const struct intel_plane_state *plane_state)
+{
+	struct drm_i915_private *dev_priv =
+		to_i915(plane_state->base.plane->dev);
+	int width = plane_state->base.crtc_w;
+	int height = plane_state->base.crtc_h;
+
+	if (width == 0 || height == 0)
+		return false;
+
+	/*
+	 * 845g/865g are only limited by the width of their cursors,
+	 * the height is arbitrary up to the precision of the register.
+	 */
+	if (!IS_ALIGNED(width, 64))
+		return false;
+
+	if (width > (IS_I845G(dev_priv) ? 64 : 512))
+		return false;
+
+	if (height > 1023)
+		return false;
+
+	return true;
+}
+
+static int i845_check_cursor(struct intel_plane *plane,
+			     struct intel_crtc_state *crtc_state,
+			     struct intel_plane_state *plane_state)
+{
+	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	unsigned int stride;
+	int ret;
+
+	ret = intel_check_cursor(crtc_state, plane_state);
+	if (ret)
+		return ret;
+
+	/* if we want to turn off the cursor ignore width and height */
+	if (!obj)
+		return 0;
+
+	/* Check for which cursor types we support */
+	if (!i845_cursor_size_ok(plane_state)) {
+		DRM_DEBUG("Cursor dimension %dx%d not supported\n",
+			  plane_state->base.crtc_w,
+			  plane_state->base.crtc_h);
+		return -EINVAL;
+	}
+
+	stride = roundup_pow_of_two(plane_state->base.crtc_w) * 4;
+	if (obj->base.size < stride * plane_state->base.crtc_h) {
+		DRM_DEBUG_KMS("buffer is too small\n");
+		return -ENOMEM;
+	}
+
+	plane_state->ctl = i845_cursor_ctl(crtc_state, plane_state);
+
+	return 0;
+}
+
 static void i845_update_cursor(struct intel_plane *plane,
 			       const struct intel_crtc_state *crtc_state,
 			       const struct intel_plane_state *plane_state)
@@ -9289,6 +9376,88 @@ static u32 i9xx_cursor_ctl(const struct intel_crtc_state *crtc_state,
 	return cntl;
 }
 
+static bool i9xx_cursor_size_ok(const struct intel_plane_state *plane_state)
+{
+	struct drm_i915_private *dev_priv =
+		to_i915(plane_state->base.plane->dev);
+	int width = plane_state->base.crtc_w;
+	int height = plane_state->base.crtc_h;
+
+	if (width == 0 || height == 0)
+		return false;
+
+	/*
+	 * Cursors are limited to a few power-of-two
+	 * sizes, and they must be square.
+	 */
+	switch (width | height) {
+	case 256:
+	case 128:
+		if (IS_GEN2(dev_priv))
+			return false;
+	case 64:
+		break;
+	default:
+		return false;
+	}
+
+	return true;
+}
+
+static int i9xx_check_cursor(struct intel_plane *plane,
+			     struct intel_crtc_state *crtc_state,
+			     struct intel_plane_state *plane_state)
+{
+	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
+	const struct drm_framebuffer *fb = plane_state->base.fb;
+	const struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+	enum pipe pipe = plane->pipe;
+	unsigned int stride;
+	int ret;
+
+	ret = intel_check_cursor(crtc_state, plane_state);
+	if (ret)
+		return ret;
+
+	/* if we want to turn off the cursor ignore width and height */
+	if (!obj)
+		return 0;
+
+	/* Check for which cursor types we support */
+	if (!i9xx_cursor_size_ok(plane_state)) {
+		DRM_DEBUG("Cursor dimension %dx%d not supported\n",
+			  plane_state->base.crtc_w,
+			  plane_state->base.crtc_h);
+		return -EINVAL;
+	}
+
+	stride = roundup_pow_of_two(plane_state->base.crtc_w) * 4;
+	if (obj->base.size < stride * plane_state->base.crtc_h) {
+		DRM_DEBUG_KMS("buffer is too small\n");
+		return -ENOMEM;
+	}
+
+	/*
+	 * There's something wrong with the cursor on CHV pipe C.
+	 * If it straddles the left edge of the screen then
+	 * moving it away from the edge or disabling it often
+	 * results in a pipe underrun, and often that can lead to
+	 * dead pipe (constant underrun reported, and it scans
+	 * out just a solid color). To recover from that, the
+	 * display power well must be turned off and on again.
+	 * Refuse the put the cursor into that compromised position.
+	 */
+	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_C &&
+	    plane_state->base.visible && plane_state->base.crtc_x < 0) {
+		DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
+		return -EINVAL;
+	}
+
+	plane_state->ctl = i9xx_cursor_ctl(crtc_state, plane_state);
+
+	return 0;
+}
+
 static void i9xx_update_cursor(struct intel_plane *plane,
 			       const struct intel_crtc_state *crtc_state,
 			       const struct intel_plane_state *plane_state)
@@ -9331,42 +9500,6 @@ static void i9xx_disable_cursor(struct intel_plane *plane,
 	i9xx_update_cursor(plane, NULL, NULL);
 }
 
-static bool cursor_size_ok(struct drm_i915_private *dev_priv,
-			   uint32_t width, uint32_t height)
-{
-	if (width == 0 || height == 0)
-		return false;
-
-	/*
-	 * 845g/865g are special in that they are only limited by
-	 * the width of their cursors, the height is arbitrary up to
-	 * the precision of the register. Everything else requires
-	 * square cursors, limited to a few power-of-two sizes.
-	 */
-	if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
-		if ((width & 63) != 0)
-			return false;
-
-		if (width > (IS_I845G(dev_priv) ? 64 : 512))
-			return false;
-
-		if (height > 1023)
-			return false;
-	} else {
-		switch (width | height) {
-		case 256:
-		case 128:
-			if (IS_GEN2(dev_priv))
-				return false;
-		case 64:
-			break;
-		default:
-			return false;
-		}
-	}
-
-	return true;
-}
 
 /* VESA 640x480x72Hz mode to set on the pipe */
 static struct drm_display_mode load_detect_mode = {
@@ -13690,73 +13823,6 @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe)
 	return ERR_PTR(ret);
 }
 
-static int
-intel_check_cursor_plane(struct intel_plane *plane,
-			 struct intel_crtc_state *crtc_state,
-			 struct intel_plane_state *state)
-{
-	struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
-	const struct drm_framebuffer *fb = state->base.fb;
-	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
-	enum pipe pipe = plane->pipe;
-	unsigned stride;
-	int ret;
-
-	ret = drm_plane_helper_check_state(&state->base,
-					   &state->clip,
-					   DRM_PLANE_HELPER_NO_SCALING,
-					   DRM_PLANE_HELPER_NO_SCALING,
-					   true, true);
-	if (ret)
-		return ret;
-
-	/* if we want to turn off the cursor ignore width and height */
-	if (!obj)
-		return 0;
-
-	/* Check for which cursor types we support */
-	if (!cursor_size_ok(dev_priv, state->base.crtc_w,
-			    state->base.crtc_h)) {
-		DRM_DEBUG("Cursor dimension %dx%d not supported\n",
-			  state->base.crtc_w, state->base.crtc_h);
-		return -EINVAL;
-	}
-
-	stride = roundup_pow_of_two(state->base.crtc_w) * 4;
-	if (obj->base.size < stride * state->base.crtc_h) {
-		DRM_DEBUG_KMS("buffer is too small\n");
-		return -ENOMEM;
-	}
-
-	if (fb->modifier != DRM_FORMAT_MOD_NONE) {
-		DRM_DEBUG_KMS("cursor cannot be tiled\n");
-		return -EINVAL;
-	}
-
-	/*
-	 * There's something wrong with the cursor on CHV pipe C.
-	 * If it straddles the left edge of the screen then
-	 * moving it away from the edge or disabling it often
-	 * results in a pipe underrun, and often that can lead to
-	 * dead pipe (constant underrun reported, and it scans
-	 * out just a solid color). To recover from that, the
-	 * display power well must be turned off and on again.
-	 * Refuse the put the cursor into that compromised position.
-	 */
-	if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_C &&
-	    state->base.visible && state->base.crtc_x < 0) {
-		DRM_DEBUG_KMS("CHV cursor C not allowed to straddle the left screen edge\n");
-		return -EINVAL;
-	}
-
-	if (IS_I845G(dev_priv) || IS_I865G(dev_priv))
-		state->ctl = i845_cursor_ctl(crtc_state, state);
-	else
-		state->ctl = i9xx_cursor_ctl(crtc_state, state);
-
-	return 0;
-}
-
 static struct intel_plane *
 intel_cursor_plane_create(struct drm_i915_private *dev_priv,
 			  enum pipe pipe)
@@ -13785,14 +13851,15 @@ intel_cursor_plane_create(struct drm_i915_private *dev_priv,
 	cursor->plane = pipe;
 	cursor->id = PLANE_CURSOR;
 	cursor->frontbuffer_bit = INTEL_FRONTBUFFER_CURSOR(pipe);
-	cursor->check_plane = intel_check_cursor_plane;
 
 	if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
 		cursor->update_plane = i845_update_cursor;
 		cursor->disable_plane = i845_disable_cursor;
+		cursor->check_plane = i845_check_cursor;
 	} else {
 		cursor->update_plane = i9xx_update_cursor;
 		cursor->disable_plane = i9xx_disable_cursor;
+		cursor->check_plane = i9xx_check_cursor;
 	}
 
 	cursor->cursor.base = ~0;
-- 
2.10.2

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

  parent reply	other threads:[~2017-03-27 18:56 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-27 18:55 [PATCH v2 00/15] drm/i915: Cursor code cleanup and cursor "FBC" support for IVB+ (v2) ville.syrjala
2017-03-27 18:55 ` [PATCH 01/15] drm/i915: Parametrize cursor/primary pipe select bits ville.syrjala
2017-03-27 18:55 ` [PATCH 02/15] drm/i915: Pass intel_plane and intel_crtc to plane hooks ville.syrjala
2017-03-27 18:55 ` [PATCH v2 03/15] drm/i915: Refactor CURBASE calculation ville.syrjala
2017-03-27 18:55 ` [PATCH 04/15] drm/i915: Clean up cursor junk from intel_crtc ville.syrjala
2017-05-04 19:42   ` Imre Deak
2017-03-27 18:55 ` [PATCH v2 05/15] drm/i915: Refactor CURPOS calculation ville.syrjala
2017-03-27 18:55 ` [PATCH v2 06/15] drm/i915: Move cursor position and base handling into the platform specific functions ville.syrjala
2017-03-27 18:55 ` [PATCH v2 07/15] drm/i915: Drop useless posting reads from cursor commit ville.syrjala
2017-03-27 18:55 ` ville.syrjala [this message]
2017-03-27 18:55 ` [PATCH 09/15] drm/i915: Generalize cursor size checks a bit ville.syrjala
2017-05-05 13:57   ` Imre Deak
2017-03-27 18:55 ` [PATCH v2 10/15] drm/i915: Use fb->pitches[0] in cursor code ville.syrjala
2017-03-27 18:55 ` [PATCH v7 11/15] drm/i915: Support variable cursor height on ivb+ ville.syrjala
2017-05-05 15:42   ` Imre Deak
2017-03-27 18:55 ` [PATCH 12/15] drm/i915: Fix gen3 physical cursor alignment requirements ville.syrjala
2017-05-05 17:48   ` Imre Deak
2017-03-27 18:55 ` [PATCH 13/15] drm/i915: Handle fb offset and src coordinates for cursors ville.syrjala
2017-05-05 20:53   ` Imre Deak
2017-03-27 18:55 ` [PATCH 14/15] drm/i915: Relax 845/865 CURBASE alignemnt requirement to 32 bytes ville.syrjala
2017-05-05 21:17   ` Imre Deak
2017-03-27 18:55 ` [PATCH 15/15] drm/i915: Simplify cursor register write sequence ville.syrjala
2017-05-05 21:31   ` Imre Deak
2017-05-10 16:38     ` Ville Syrjälä
2017-03-27 19:14 ` ✓ Fi.CI.BAT: success for drm/i915: Cursor code cleanup and cursor "FBC" support for IVB+ (rev2) Patchwork

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=20170327185546.2977-9-ville.syrjala@linux.intel.com \
    --to=ville.syrjala@linux.intel.com \
    --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.