drm/i915: Add rotation support for cursor plane (v5)
authorVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 23 Oct 2014 14:41:34 +0000 (07:41 -0700)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Fri, 24 Oct 2014 14:34:14 +0000 (16:34 +0200)
The cursor plane also supports 180 degree rotation. Add a new
"cursor-rotation" property on the crtc which controls this.

Unlike sprites, the cursor has a fixed size, so if you have a small
cursor image with the rest of the bo filled by transparent pixels,
simply flipping the rotation property will cause the visible part
of the cursor to shift. This is something to keep in mind when
using cursor rotation.

v2: Fix gen4/vlv by offsetting the base address appropriately

v3: Removing cursor-rotation property and using rotation property on cursor
plane.
v4: Changing the author name back to Ville.

v5 (by Matt Roper): Slight tweaking to apply against latest di-nightly
codebase.

Cc: Sagar Kamble <sagar.a.kamble@intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
Tested-by (IVB): Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c

index 1e6f7fb15672d9753f8fa57e8a20799cd5d7d598..ea84e1ec5e5f23e4d35726c0c4d4e577987572b2 100644 (file)
@@ -4208,6 +4208,7 @@ enum punit_power_well {
 #define   MCURSOR_PIPE_A       0x00
 #define   MCURSOR_PIPE_B       (1 << 28)
 #define   MCURSOR_GAMMA_ENABLE  (1 << 26)
+#define   CURSOR_ROTATE_180    (1<<15)
 #define   CURSOR_TRICKLE_FEED_DISABLE  (1 << 14)
 #define _CURABASE              0x70084
 #define _CURAPOS               0x70088
index fb9a4348068082f8fb21a7409696339402e347d4..1d2fa7f4523e00feb3d2407623241edb657c17bb 100644 (file)
@@ -8343,6 +8343,9 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base)
                        cntl |= CURSOR_PIPE_CSC_ENABLE;
        }
 
+       if (to_intel_plane(crtc->cursor)->rotation == BIT(DRM_ROTATE_180))
+               cntl |= CURSOR_ROTATE_180;
+
        if (intel_crtc->cursor_cntl != cntl) {
                I915_WRITE(CURCNTR(pipe), cntl);
                POSTING_READ(CURCNTR(pipe));
@@ -8400,6 +8403,13 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc,
 
        I915_WRITE(CURPOS(pipe), pos);
 
+       /* ILK+ do this automagically */
+       if (HAS_GMCH_DISPLAY(dev) &&
+               to_intel_plane(crtc->cursor)->rotation == BIT(DRM_ROTATE_180)) {
+               base += (intel_crtc->cursor_height *
+                       intel_crtc->cursor_width - 1) * 4;
+       }
+
        if (IS_845G(dev) || IS_I865G(dev))
                i845_update_cursor(crtc, base);
        else
@@ -12010,6 +12020,7 @@ static const struct drm_plane_funcs intel_cursor_plane_funcs = {
        .update_plane = intel_cursor_plane_update,
        .disable_plane = intel_cursor_plane_disable,
        .destroy = intel_plane_destroy,
+       .set_property = intel_plane_set_property,
 };
 
 static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
@@ -12025,12 +12036,26 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev,
        cursor->max_downscale = 1;
        cursor->pipe = pipe;
        cursor->plane = pipe;
+       cursor->rotation = BIT(DRM_ROTATE_0);
 
        drm_universal_plane_init(dev, &cursor->base, 0,
                                 &intel_cursor_plane_funcs,
                                 intel_cursor_formats,
                                 ARRAY_SIZE(intel_cursor_formats),
                                 DRM_PLANE_TYPE_CURSOR);
+
+       if (INTEL_INFO(dev)->gen >= 4) {
+               if (!dev->mode_config.rotation_property)
+                       dev->mode_config.rotation_property =
+                               drm_mode_create_rotation_property(dev,
+                                                       BIT(DRM_ROTATE_0) |
+                                                       BIT(DRM_ROTATE_180));
+               if (dev->mode_config.rotation_property)
+                       drm_object_attach_property(&cursor->base.base,
+                               dev->mode_config.rotation_property,
+                               cursor->rotation);
+       }
+
        return &cursor->base;
 }