public inbox for intel-gfx@lists.freedesktop.org
 help / color / mirror / Atom feed
From: sonika.jindal@intel.com
To: intel-gfx@lists.freedesktop.org
Cc: Sagar Kamble <sagar.a.kamble@intel.com>
Subject: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
Date: Tue, 15 Jul 2014 14:10:28 +0530	[thread overview]
Message-ID: <1405413629-4266-6-git-send-email-sonika.jindal@intel.com> (raw)
In-Reply-To: <1405413629-4266-1-git-send-email-sonika.jindal@intel.com>

From: Sonika Jindal <sonika.jindal@intel.com>

Primary planes support 180 degree rotation. Expose the feature
through rotation drm property.

v2: Calculating linear/tiled offsets based on pipe source width and
height. Added 180 degree rotation support in ironlake_update_plane.

v3: Checking if CRTC is active before issueing update_plane. Added
wait for vblank to make sure we dont overtake page flips. Disabling
FBC since it does not work with rotated planes.

v4: Updated rotation checks for pending flips, fbc disable. Creating
rotation property only for Gen4 onwards. Property resetting as part
of lastclose.

v5: Resetting property in i915_driver_lastclose properly for planes
and crtcs. Fixed linear offset calculation that was off by 1 w.r.t
width in i9xx_update_plane and ironlake_update_plane. Removed tab
based indentation and unnecessary braces in intel_crtc_set_property
and intel_update_fbc. FBC and flip related checks should be done only
for valid crtcs.

v6: Minor nits in FBC disable checks for comments in intel_crtc_set_property
and positioning the disable code in intel_update_fbc.

v7: In case rotation property on inactive crtc is updated, we return
successfully printing debug log as crtc is inactive and only property change
is preserved.

v8: update_plane is changed to update_primary_plane, crtc->fb is changed to
crtc->primary->fb  and return value of update_primary_plane is ignored.

v9: added rotation property to primary plane instead of crtc. Removing reset
of rotation property from lastclose. rotation_property is moved to
drm_mode_config, so drm layer will take care of resetting. Adding updation of
fbc when rotation is set to 0. Allowing rotation only if value is
different than old one.

Testcase: igt/kms_rotation_crc

Signed-off-by: Uma Shankar <uma.shankar@intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |  104 ++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_pm.c      |    6 ++
 3 files changed, 107 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 74283d5..f39e2e7 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4107,6 +4107,7 @@ enum punit_power_well {
 #define   DISPPLANE_NO_LINE_DOUBLE		0
 #define   DISPPLANE_STEREO_POLARITY_FIRST	0
 #define   DISPPLANE_STEREO_POLARITY_SECOND	(1<<18)
+#define   DISPPLANE_ROTATE_180         (1<<15)
 #define   DISPPLANE_TRICKLE_FEED_DISABLE	(1<<14) /* Ironlake */
 #define   DISPPLANE_TILED			(1<<10)
 #define _DSPAADDR				0x70184
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 023c770..e881dcf 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2408,11 +2408,15 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg;
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	reg = DSPCNTR(plane);
 	dspcntr = I915_READ(reg);
 	/* Mask out pixel format bits in case we change it */
 	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+	dspcntr &= ~DISPPLANE_ROTATE_180;
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_C8:
 		dspcntr |= DISPPLANE_8BPP;
@@ -2454,8 +2458,6 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	if (IS_G4X(dev))
 		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
 
-	I915_WRITE(reg, dspcntr);
-
 	linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
 
 	if (INTEL_INFO(dev)->gen >= 4) {
@@ -2467,6 +2469,17 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	} else {
 		intel_crtc->dspaddr_offset = linear_offset;
 	}
+	if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) {
+		dspcntr |= DISPPLANE_ROTATE_180;
+
+		x += (intel_crtc->config.pipe_src_w - 1);
+		y += (intel_crtc->config.pipe_src_h - 1);
+		linear_offset += (intel_crtc->config.pipe_src_h - 1) *
+			fb->pitches[0] +
+			(intel_crtc->config.pipe_src_w - 1) * pixel_size;
+	}
+
+	I915_WRITE(reg, dspcntr);
 
 	DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
 		      i915_gem_obj_ggtt_offset(obj), linear_offset, x, y,
@@ -2494,11 +2507,14 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg;
+	int pixel_size;
 
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 	reg = DSPCNTR(plane);
 	dspcntr = I915_READ(reg);
 	/* Mask out pixel format bits in case we change it */
 	dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+	dspcntr &= ~DISPPLANE_ROTATE_180;
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_C8:
 		dspcntr |= DISPPLANE_8BPP;
@@ -2536,14 +2552,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	else
 		dspcntr |= DISPPLANE_TRICKLE_FEED_DISABLE;
 
-	I915_WRITE(reg, dspcntr);
-
 	linear_offset = y * fb->pitches[0] + x * (fb->bits_per_pixel / 8);
 	intel_crtc->dspaddr_offset =
 		intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
 					       fb->bits_per_pixel / 8,
 					       fb->pitches[0]);
 	linear_offset -= intel_crtc->dspaddr_offset;
+	if (to_intel_plane(crtc->primary)->rotation == BIT(DRM_ROTATE_180)) {
+		dspcntr |= DISPPLANE_ROTATE_180;
+
+		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
+			x += (intel_crtc->config.pipe_src_w - 1);
+			y += (intel_crtc->config.pipe_src_h - 1);
+			linear_offset +=
+			(intel_crtc->config.pipe_src_h - 1) *
+			fb->pitches[0] + (intel_crtc->config.pipe_src_w - 1) *
+			pixel_size;
+		}
+	}
+
+	I915_WRITE(reg, dspcntr);
 
 	DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n",
 		      i915_gem_obj_ggtt_offset(obj), linear_offset, x, y,
@@ -11576,11 +11604,65 @@ static void intel_plane_destroy(struct drm_plane *plane)
 	drm_plane_cleanup(plane);
 	kfree(intel_plane);
 }
+static int intel_primary_plane_set_property(struct drm_plane *plane,
+				    struct drm_property *prop,
+				    uint64_t val)
+{
+	struct drm_device *dev = plane->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	struct drm_crtc *crtc = plane->crtc;
+	struct intel_crtc *intel_crtc;
+	uint64_t old_val;
+
+	if (prop == dev->mode_config.rotation_property) {
+		/* exactly one rotation angle please */
+		if (hweight32(val & 0xf) != 1)
+			return -EINVAL;
+
+		old_val = intel_plane->rotation;
+		intel_plane->rotation = val;
+
+		if (old_val == intel_plane->rotation)
+			return 0;
+
+		intel_crtc = to_intel_crtc(plane->crtc);
+
+		if (intel_crtc && intel_crtc->active &&
+				intel_crtc->primary_enabled) {
+			intel_crtc_wait_for_pending_flips(crtc);
+
+		/* FBC does not work on some platforms for rotated planes */
+			if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev)) {
+				if (dev_priv->fbc.plane == intel_crtc->plane &&
+				intel_plane->rotation != BIT(DRM_ROTATE_0))
+					intel_disable_fbc(dev);
+			/* If rotation was set earlier and new rotation is 0,
+			we might have disabled fbc earlier. So update it now */
+				else if (intel_plane->rotation == BIT(DRM_ROTATE_0)
+					&& old_val != BIT(DRM_ROTATE_0)) {
+					mutex_lock(&dev->struct_mutex);
+					intel_update_fbc(dev);
+					mutex_unlock(&dev->struct_mutex);
+				}
+			}
+
+			dev_priv->display.update_primary_plane(crtc,
+				crtc->primary->fb, 0, 0);
+
+		} else {
+			DRM_DEBUG_KMS("[CRTC:%d] inactive. Only rotation"
+				"property is updated\n", crtc->base.id);
+		}
+	}
+	return 0;
+}
 
 static const struct drm_plane_funcs intel_primary_plane_funcs = {
 	.update_plane = intel_primary_plane_setplane,
 	.disable_plane = intel_primary_plane_disable,
 	.destroy = intel_plane_destroy,
+	.set_property = intel_primary_plane_set_property
 };
 
 static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
@@ -11598,6 +11680,7 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
 	primary->max_downscale = 1;
 	primary->pipe = pipe;
 	primary->plane = pipe;
+	primary->rotation = BIT(DRM_ROTATE_0);
 	if (HAS_FBC(dev) && INTEL_INFO(dev)->gen < 4)
 		primary->plane = !pipe;
 
@@ -11613,6 +11696,19 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
 				 &intel_primary_plane_funcs,
 				 intel_primary_formats, num_formats,
 				 DRM_PLANE_TYPE_PRIMARY);
+
+	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(&primary->base.base,
+				dev->mode_config.rotation_property,
+				primary->rotation);
+	}
+
 	return &primary->base;
 }
 
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 9585f15..0210b1e 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -578,6 +578,12 @@ void intel_update_fbc(struct drm_device *dev)
 			DRM_DEBUG_KMS("framebuffer not tiled or fenced, disabling compression\n");
 		goto out_disable;
 	}
+	if (INTEL_INFO(dev)->gen <= 4 && !IS_G4X(dev) &&
+	    to_intel_plane(crtc->primary)->rotation != BIT(DRM_ROTATE_0)) {
+		if (set_no_fbc_reason(dev_priv, FBC_UNSUPPORTED_MODE))
+			DRM_DEBUG_KMS("Rotation unsupported, disabling\n");
+		goto out_disable;
+	}
 
 	/* If the kernel debugger is active, always disable compression */
 	if (in_dbg_master())
-- 
1.7.10.4

  parent reply	other threads:[~2014-07-15  8:44 UTC|newest]

Thread overview: 60+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-15  8:40 [PATCH 0/6] Add 180 degree primary and sprite rotation sonika.jindal
2014-07-15  8:40 ` [PATCH 1/6] drm/i915: Add 180 degree sprite rotation support sonika.jindal
2014-07-15  8:40 ` [PATCH 2/6] drm/i915: Make intel_plane_restore() return an error sonika.jindal
2014-07-15  8:40 ` [PATCH 3/6] drm: Add rotation_property to mode_config sonika.jindal
2014-07-15 12:13   ` [PATCH] drm: Add rotation_property to mode_config and creating it sonika.jindal
2014-07-28 15:29     ` Ville Syrjälä
2014-07-28 18:47       ` Daniel Vetter
2014-07-29  9:40         ` Ville Syrjälä
2014-07-29 10:30           ` Daniel Vetter
2014-07-31  4:09             ` Jindal, Sonika
2014-08-04 10:29               ` Jindal, Sonika
2014-08-04 11:54                 ` Ville Syrjälä
2014-08-04 12:04                   ` Jindal, Sonika
2014-07-15  8:40 ` [PATCH 4/6] drm/i915: Add rotation property for sprites sonika.jindal
2014-07-15 12:12   ` [PATCH] " sonika.jindal
2014-07-15  8:40 ` sonika.jindal [this message]
2014-07-15  9:11   ` [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support Daniel Vetter
2014-07-15  9:38     ` Jindal, Sonika
2014-07-15 10:31       ` Daniel Vetter
2014-07-15 11:30     ` [PATCH 0/3 v2] Moving creation of rotation_property to drm layer sonika.jindal
2014-07-15 11:30       ` [PATCH 1/4] drm: Add rotation_property to mode_config and creating it sonika.jindal
2014-07-15 11:30       ` [PATCH 2/4] drm/i915: Add rotation property for sprites sonika.jindal
2014-07-15 11:30       ` [PATCH 3/4] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
2014-07-15 12:02       ` [PATCH 0/3 v2] Moving creation of rotation_property to drm layer Daniel Vetter
2014-07-15 12:10         ` Jindal, Sonika
2014-07-15 12:10     ` [PATCH] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
2014-08-07 11:45     ` [PATCH 5/6] " Daniel Vetter
2014-08-07 12:11       ` Daniel Vetter
2014-08-11 11:07         ` Jindal, Sonika
2014-08-11 11:42           ` Daniel Vetter
2014-08-11 12:07             ` Jindal, Sonika
2014-08-11 12:23               ` Daniel Vetter
2014-08-12  3:25                 ` Jindal, Sonika
2014-08-19  6:26                   ` [PATCH 0/2] 180 Primary plane rotation: calling setplane in set_property sonika.jindal
2014-08-19  6:26                     ` [PATCH 1/2] drm/i915: Updating plane parameters for primary plane in setplane sonika.jindal
2014-08-19 20:50                       ` Matt Roper
2014-08-20  5:53                         ` Jindal, Sonika
2014-08-21  6:14                           ` sonika.jindal
2014-08-25 20:42                             ` Daniel Vetter
2014-08-19  6:26                     ` [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
2014-08-19 22:51                       ` Matt Roper
2014-08-20  5:36                         ` Jindal, Sonika
2014-08-21  6:15                           ` sonika.jindal
2014-08-21  8:33                             ` Ville Syrjälä
2014-08-21 11:44                               ` Jindal, Sonika
2014-08-21 13:37                                 ` Ville Syrjälä
2014-08-22  3:59                                   ` Jindal, Sonika
2014-08-22  6:58                                     ` [PATCH] " sonika.jindal
2014-08-22  8:14                                     ` [PATCH 2/2] " Ville Syrjälä
2014-08-22  8:22                                       ` Jindal, Sonika
2014-08-22  8:36                                       ` [PATCH] " sonika.jindal
2014-08-25 20:50                                         ` Daniel Vetter
2014-07-15  8:40 ` [PATCH 6/6] drm: Resetting rotation property sonika.jindal
2014-08-04 12:01   ` Ville Syrjälä
2014-08-04 12:03     ` Jindal, Sonika
2014-07-15 10:52 ` [PATCH 0/6] Add 180 degree primary and sprite rotation Damien Lespiau
2014-07-15 10:55   ` Jindal, Sonika
2014-07-15 10:57     ` Damien Lespiau
  -- strict thread matches above, loose matches on Subject: below --
2014-08-05  5:56 [PATCH 0/6 v2] " sonika.jindal
2014-08-05  5:56 ` [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
2014-08-06  4:25 [PATCH 0/6 v2] Add 180 degree primary and sprite rotation sonika.jindal
2014-08-06  4:25 ` [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support sonika.jindal

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=1405413629-4266-6-git-send-email-sonika.jindal@intel.com \
    --to=sonika.jindal@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=sagar.a.kamble@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox