From: Ville Syrjälä <ville.syrj...@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.

Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_display.c | 232 ++++++++++++++++++++++-------------
 1 file changed, 145 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index 222f54ffd113..41cbaee66f1b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9269,6 +9269,74 @@ static void i845_disable_cursor(struct intel_plane 
*plane,
        i845_update_cursor(plane, NULL, NULL);
 }
 
+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 ((width & 63) != 0)
+               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 *state)
+{
+       struct drm_framebuffer *fb = state->base.fb;
+       struct drm_i915_gem_object *obj = intel_fb_obj(fb);
+       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 (!i845_cursor_size_ok(state)) {
+               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;
+       }
+
+       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)
@@ -9328,41 +9396,92 @@ 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)
+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;
 
        /*
-        * 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.
+        * Cursors are limited to a few power-of-two
+        * sizes, and they must be square.
         */
-       if (IS_I845G(dev_priv) || IS_I865G(dev_priv)) {
-               if ((width & 63) != 0)
+       switch (width | height) {
+       case 256:
+       case 128:
+               if (IS_GEN2(dev_priv))
                        return false;
+       case 64:
+               break;
+       default:
+               return false;
+       }
 
-               if (width > (IS_I845G(dev_priv) ? 64 : 512))
-                       return false;
+       return true;
+}
 
-               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;
-               }
+static int i9xx_check_cursor(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);
+       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 (!i9xx_cursor_size_ok(state)) {
+               DRM_DEBUG("Cursor dimension %dx%d not supported\n",
+                         state->base.crtc_w, state->base.crtc_h);
+               return -EINVAL;
        }
 
-       return true;
+       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;
+       }
+
+       return 0;
 }
 
 /* VESA 640x480x72Hz mode to set on the pipe */
@@ -13671,68 +13790,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);
-       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;
-       }
-
-       return 0;
-}
-
 static struct intel_plane *
 intel_cursor_plane_create(struct drm_i915_private *dev_priv,
                          enum pipe pipe)
@@ -13761,14 +13818,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

Reply via email to