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

The primary and sprite planes on CHV pipe B support horizontal
mirroring. Expose it to the world.

Sadly the hardware ignores the mirror bit when the rotate bit is
set, so we'll have to reject the 180+X case.

v2: Drop the BIT()

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen at linux.intel.com> (v1)
---
 drivers/gpu/drm/i915/intel_atomic_plane.c | 8 ++++++++
 drivers/gpu/drm/i915/intel_display.c      | 9 +++++++++
 drivers/gpu/drm/i915/intel_sprite.c       | 9 +++++++++
 3 files changed, 26 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c 
b/drivers/gpu/drm/i915/intel_atomic_plane.c
index c762ae549a1c..45e67e3842db 100644
--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
@@ -169,6 +169,14 @@ static int intel_plane_atomic_check(struct drm_plane 
*plane,
                }
        }

+       /* CHV ignores the mirror bit when the rotate bit is set :( */
+       if (IS_CHERRYVIEW(plane->dev) &&
+           state->rotation & DRM_ROTATE_180 &&
+           state->rotation & DRM_REFLECT_X) {
+               DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
+               return -EINVAL;
+       }
+
        intel_state->base.visible = false;
        ret = intel_plane->check_plane(plane, crtc_state, intel_state);
        if (ret)
diff --git a/drivers/gpu/drm/i915/intel_display.c 
b/drivers/gpu/drm/i915/intel_display.c
index c8fa35e921f9..5a347469bf39 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -3074,6 +3074,9 @@ static void i9xx_update_primary_plane(struct drm_plane 
*primary,
        if (rotation & DRM_ROTATE_180)
                dspcntr |= DISPPLANE_ROTATE_180;

+       if (rotation & DRM_REFLECT_X)
+               dspcntr |= DISPPLANE_MIRROR;
+
        if (IS_G4X(dev))
                dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;

@@ -3086,6 +3089,8 @@ static void i9xx_update_primary_plane(struct drm_plane 
*primary,
        if (rotation & DRM_ROTATE_180) {
                x += crtc_state->pipe_src_w - 1;
                y += crtc_state->pipe_src_h - 1;
+       } else if (rotation & DRM_REFLECT_X) {
+               x += crtc_state->pipe_src_w - 1;
        }

        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
@@ -14963,6 +14968,10 @@ static struct drm_plane 
*intel_primary_plane_create(struct drm_device *dev,
                supported_rotations =
                        DRM_ROTATE_0 | DRM_ROTATE_90 |
                        DRM_ROTATE_180 | DRM_ROTATE_270;
+       } else if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) {
+               supported_rotations =
+                       DRM_ROTATE_0 | DRM_ROTATE_180 |
+                       DRM_REFLECT_X;
        } else if (INTEL_GEN(dev) >= 4) {
                supported_rotations =
                        DRM_ROTATE_0 | DRM_ROTATE_180;
diff --git a/drivers/gpu/drm/i915/intel_sprite.c 
b/drivers/gpu/drm/i915/intel_sprite.c
index 3670f462888f..7f3e419786d6 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -426,6 +426,9 @@ vlv_update_plane(struct drm_plane *dplane,
        if (rotation & DRM_ROTATE_180)
                sprctl |= SP_ROTATE_180;

+       if (rotation & DRM_REFLECT_X)
+               sprctl |= SP_MIRROR;
+
        /* Sizes are 0 based */
        src_w--;
        src_h--;
@@ -438,6 +441,8 @@ vlv_update_plane(struct drm_plane *dplane,
        if (rotation & DRM_ROTATE_180) {
                x += src_w;
                y += src_h;
+       } else if (rotation & DRM_REFLECT_X) {
+               x += src_w;
        }

        linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
@@ -1128,6 +1133,10 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, 
int plane)
                supported_rotations =
                        DRM_ROTATE_0 | DRM_ROTATE_90 |
                        DRM_ROTATE_180 | DRM_ROTATE_270;
+       } else if (IS_CHERRYVIEW(dev) && pipe == PIPE_B) {
+               supported_rotations =
+                       DRM_ROTATE_0 | DRM_ROTATE_180 |
+                       DRM_REFLECT_X;
        } else {
                supported_rotations =
                        DRM_ROTATE_0 | DRM_ROTATE_180;
-- 
2.7.4

Reply via email to