All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] Add 180 degree primary and sprite rotation
@ 2014-07-15  8:40 sonika.jindal
  2014-07-15  8:40 ` [PATCH 1/6] drm/i915: Add 180 degree sprite rotation support sonika.jindal
                   ` (6 more replies)
  0 siblings, 7 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15  8:40 UTC (permalink / raw)
  To: intel-gfx

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

This patchset provides support for 0/180 degree hardare rotaion for primary and
sprite planes. The rotation property is now made global and is part of
drm_mode_config. It is attached to different planes.

Sonika Jindal (3):
  drm: Add rotation_property to mode_config
  drm/i915: Add 180 degree primary plane rotation support
  drm: Resetting rotation property

Ville Syrjälä (3):
  drm/i915: Add 180 degree sprite rotation support
  drm/i915: Make intel_plane_restore() return an error
  drm/i915: Add rotation property for sprites

 drivers/gpu/drm/drm_fb_helper.c      |   10 +++-
 drivers/gpu/drm/i915/i915_reg.h      |    4 ++
 drivers/gpu/drm/i915/intel_display.c |  104 ++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_drv.h     |    3 +-
 drivers/gpu/drm/i915/intel_pm.c      |    6 ++
 drivers/gpu/drm/i915/intel_sprite.c  |   93 +++++++++++++++++++++++++++---
 include/drm/drm_crtc.h               |    1 +
 7 files changed, 207 insertions(+), 14 deletions(-)

-- 
1.7.10.4

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 1/6] drm/i915: Add 180 degree sprite rotation support
  2014-07-15  8:40 [PATCH 0/6] Add 180 degree primary and sprite rotation sonika.jindal
@ 2014-07-15  8:40 ` sonika.jindal
  2014-07-15  8:40 ` [PATCH 2/6] drm/i915: Make intel_plane_restore() return an error sonika.jindal
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15  8:40 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sagar Kamble, dri-devel

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

The sprite planes (in fact all display planes starting from gen4)
support 180 degree rotation. Add the relevant low level bits to the
sprite code to make use of that feature.

The upper layers are not yet plugged in.

v2: HSW handles the rotated buffer offset automagically

v3: BDW also handles the rotated buffer offset automagically

Testcase: igt/kms_rotation_crc
Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sagar Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/i915_reg.h     |    3 +++
 drivers/gpu/drm/i915/intel_drv.h    |    1 +
 drivers/gpu/drm/i915/intel_sprite.c |   38 +++++++++++++++++++++++++++++++++++
 3 files changed, 42 insertions(+)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index ce70aa4..74283d5 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4191,6 +4191,7 @@ enum punit_power_well {
 #define   DVS_YUV_ORDER_UYVY	(1<<16)
 #define   DVS_YUV_ORDER_YVYU	(2<<16)
 #define   DVS_YUV_ORDER_VYUY	(3<<16)
+#define   DVS_ROTATE_180	(1<<15)
 #define   DVS_DEST_KEY		(1<<2)
 #define   DVS_TRICKLE_FEED_DISABLE (1<<14)
 #define   DVS_TILED		(1<<10)
@@ -4261,6 +4262,7 @@ enum punit_power_well {
 #define   SPRITE_YUV_ORDER_UYVY		(1<<16)
 #define   SPRITE_YUV_ORDER_YVYU		(2<<16)
 #define   SPRITE_YUV_ORDER_VYUY		(3<<16)
+#define   SPRITE_ROTATE_180		(1<<15)
 #define   SPRITE_TRICKLE_FEED_DISABLE	(1<<14)
 #define   SPRITE_INT_GAMMA_ENABLE	(1<<13)
 #define   SPRITE_TILED			(1<<10)
@@ -4334,6 +4336,7 @@ enum punit_power_well {
 #define   SP_YUV_ORDER_UYVY		(1<<16)
 #define   SP_YUV_ORDER_YVYU		(2<<16)
 #define   SP_YUV_ORDER_VYUY		(3<<16)
+#define   SP_ROTATE_180			(1<<15)
 #define   SP_TILED			(1<<10)
 #define _SPALINOFF		(VLV_DISPLAY_BASE + 0x72184)
 #define _SPASTRIDE		(VLV_DISPLAY_BASE + 0x72188)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index f80c6ef..88afa44 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -439,6 +439,7 @@ struct intel_plane {
 	unsigned int crtc_w, crtc_h;
 	uint32_t src_x, src_y;
 	uint32_t src_w, src_h;
+	unsigned int rotation;
 
 	/* Since we need to change the watermarks before/after
 	 * enabling/disabling the planes, we need to store the parameters here
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 985317e..12025fd 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -163,6 +163,7 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
 	sprctl &= ~SP_PIXFORMAT_MASK;
 	sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
 	sprctl &= ~SP_TILED;
+	sprctl &= ~SP_ROTATE_180;
 
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_YUYV:
@@ -234,6 +235,14 @@ vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
 							fb->pitches[0]);
 	linear_offset -= sprsurf_offset;
 
+	if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+		sprctl |= SP_ROTATE_180;
+
+		x += src_w;
+		y += src_h;
+		linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
+	}
+
 	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
 
 	intel_update_primary_plane(intel_crtc);
@@ -363,6 +372,7 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	sprctl &= ~SPRITE_RGB_ORDER_RGBX;
 	sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
 	sprctl &= ~SPRITE_TILED;
+	sprctl &= ~SPRITE_ROTATE_180;
 
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_XBGR8888:
@@ -424,6 +434,18 @@ ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 					       pixel_size, fb->pitches[0]);
 	linear_offset -= sprsurf_offset;
 
+	if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+		sprctl |= SPRITE_ROTATE_180;
+
+		/* HSW and BDW does this automagically in hardware */
+		if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
+			x += src_w;
+			y += src_h;
+			linear_offset += src_h * fb->pitches[0] +
+				src_w * pixel_size;
+		}
+	}
+
 	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
 
 	intel_update_primary_plane(intel_crtc);
@@ -569,6 +591,7 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	dvscntr &= ~DVS_RGB_ORDER_XBGR;
 	dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
 	dvscntr &= ~DVS_TILED;
+	dvscntr &= ~DVS_ROTATE_180;
 
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_XBGR8888:
@@ -625,6 +648,14 @@ ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 					       pixel_size, fb->pitches[0]);
 	linear_offset -= dvssurf_offset;
 
+	if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
+		dvscntr |= DVS_ROTATE_180;
+
+		x += src_w;
+		y += src_h;
+		linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
+	}
+
 	atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
 
 	intel_update_primary_plane(intel_crtc);
@@ -892,6 +923,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 	max_scale = intel_plane->max_downscale << 16;
 	min_scale = intel_plane->can_scale ? 1 : (1 << 16);
 
+	drm_rect_rotate(&src, fb->width << 16, fb->height << 16,
+			intel_plane->rotation);
+
 	hscale = drm_rect_calc_hscale_relaxed(&src, &dst, min_scale, max_scale);
 	BUG_ON(hscale < 0);
 
@@ -930,6 +964,9 @@ intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
 				     drm_rect_width(&dst) * hscale - drm_rect_width(&src),
 				     drm_rect_height(&dst) * vscale - drm_rect_height(&src));
 
+		drm_rect_rotate_inv(&src, fb->width << 16, fb->height << 16,
+				    intel_plane->rotation);
+
 		/* sanity check to make sure the src viewport wasn't enlarged */
 		WARN_ON(src.x1 < (int) src_x ||
 			src.y1 < (int) src_y ||
@@ -1311,6 +1348,7 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 
 	intel_plane->pipe = pipe;
 	intel_plane->plane = plane;
+	intel_plane->rotation = BIT(DRM_ROTATE_0);
 	possible_crtcs = (1 << pipe);
 	ret = drm_plane_init(dev, &intel_plane->base, possible_crtcs,
 			     &intel_plane_funcs,
-- 
1.7.10.4

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 2/6] drm/i915: Make intel_plane_restore() return an error
  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 ` sonika.jindal
  2014-07-15  8:40 ` [PATCH 3/6] drm: Add rotation_property to mode_config sonika.jindal
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15  8:40 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

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

Propagate the error from intel_update_plane() up through
intel_plane_restore() to the caller. This will be used for
rollback purposes when setting properties fails.

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h    |    2 +-
 drivers/gpu/drm/i915/intel_sprite.c |   14 +++++++-------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 88afa44..9bc7fff 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1028,7 +1028,7 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
 int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
 void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
 			       enum plane plane);
-void intel_plane_restore(struct drm_plane *plane);
+int intel_plane_restore(struct drm_plane *plane);
 void intel_plane_disable(struct drm_plane *plane);
 int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
 			      struct drm_file *file_priv);
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 12025fd..9fb7523 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1218,18 +1218,18 @@ out_unlock:
 	return ret;
 }
 
-void intel_plane_restore(struct drm_plane *plane)
+int intel_plane_restore(struct drm_plane *plane)
 {
 	struct intel_plane *intel_plane = to_intel_plane(plane);
 
 	if (!plane->crtc || !plane->fb)
-		return;
+		return 0;
 
-	intel_update_plane(plane, plane->crtc, plane->fb,
-			   intel_plane->crtc_x, intel_plane->crtc_y,
-			   intel_plane->crtc_w, intel_plane->crtc_h,
-			   intel_plane->src_x, intel_plane->src_y,
-			   intel_plane->src_w, intel_plane->src_h);
+	return intel_update_plane(plane, plane->crtc, plane->fb,
+				  intel_plane->crtc_x, intel_plane->crtc_y,
+				  intel_plane->crtc_w, intel_plane->crtc_h,
+				  intel_plane->src_x, intel_plane->src_y,
+				  intel_plane->src_w, intel_plane->src_h);
 }
 
 void intel_plane_disable(struct drm_plane *plane)
-- 
1.7.10.4

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 3/6] drm: Add rotation_property to mode_config
  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 ` sonika.jindal
  2014-07-15 12:13   ` [PATCH] drm: Add rotation_property to mode_config and creating it sonika.jindal
  2014-07-15  8:40 ` [PATCH 4/6] drm/i915: Add rotation property for sprites sonika.jindal
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-07-15  8:40 UTC (permalink / raw)
  To: intel-gfx

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

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 include/drm/drm_crtc.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index ce6df4a..5545dd3 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -819,6 +819,7 @@ struct drm_mode_config {
 	struct drm_property *dpms_property;
 	struct drm_property *path_property;
 	struct drm_property *plane_type_property;
+	struct drm_property *rotation_property;
 
 	/* DVI-I properties */
 	struct drm_property *dvi_i_subconnector_property;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 4/6] drm/i915: Add rotation property for sprites
  2014-07-15  8:40 [PATCH 0/6] Add 180 degree primary and sprite rotation sonika.jindal
                   ` (2 preceding siblings ...)
  2014-07-15  8:40 ` [PATCH 3/6] drm: Add rotation_property to mode_config sonika.jindal
@ 2014-07-15  8:40 ` sonika.jindal
  2014-07-15 12:12   ` [PATCH] " sonika.jindal
  2014-07-15  8:40 ` [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-07-15  8:40 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

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

Sprite planes support 180 degree rotation. The lower layers are now in
place, so hook in the standard rotation property to expose the feature
to the users.

v2: Moving rotation_property to mode_config

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c |   41 ++++++++++++++++++++++++++++++++++-
 1 file changed, 40 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 9fb7523..94a138d 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1218,6 +1218,30 @@ out_unlock:
 	return ret;
 }
 
+static int intel_plane_set_property(struct drm_plane *plane,
+				    struct drm_property *prop,
+				    uint64_t val)
+{
+	struct drm_device *dev = plane->dev;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	uint64_t old_val;
+	int ret = -ENOENT;
+
+	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;
+		ret = intel_plane_restore(plane);
+		if (ret)
+			intel_plane->rotation = old_val;
+	}
+
+	return ret;
+}
+
 int intel_plane_restore(struct drm_plane *plane)
 {
 	struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -1244,6 +1268,7 @@ static const struct drm_plane_funcs intel_plane_funcs = {
 	.update_plane = intel_update_plane,
 	.disable_plane = intel_disable_plane,
 	.destroy = intel_destroy_plane,
+	.set_property = intel_plane_set_property,
 };
 
 static uint32_t ilk_plane_formats[] = {
@@ -1354,8 +1379,22 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 			     &intel_plane_funcs,
 			     plane_formats, num_plane_formats,
 			     false);
-	if (ret)
+	if (ret) {
 		kfree(intel_plane);
+		goto out;
+	}
+
+	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(&intel_plane->base.base,
+					   dev->mode_config.rotation_property,
+					   intel_plane->rotation);
 
+ out:
 	return ret;
 }
-- 
1.7.10.4

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-07-15  8:40 [PATCH 0/6] Add 180 degree primary and sprite rotation sonika.jindal
                   ` (3 preceding siblings ...)
  2014-07-15  8:40 ` [PATCH 4/6] drm/i915: Add rotation property for sprites sonika.jindal
@ 2014-07-15  8:40 ` sonika.jindal
  2014-07-15  9:11   ` Daniel Vetter
  2014-07-15  8:40 ` [PATCH 6/6] drm: Resetting rotation property sonika.jindal
  2014-07-15 10:52 ` [PATCH 0/6] Add 180 degree primary and sprite rotation Damien Lespiau
  6 siblings, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-07-15  8:40 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sagar Kamble

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 6/6] drm: Resetting rotation property
  2014-07-15  8:40 [PATCH 0/6] Add 180 degree primary and sprite rotation sonika.jindal
                   ` (4 preceding siblings ...)
  2014-07-15  8:40 ` [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
@ 2014-07-15  8:40 ` sonika.jindal
  2014-08-04 12:01   ` Ville Syrjälä
  2014-07-15 10:52 ` [PATCH 0/6] Add 180 degree primary and sprite rotation Damien Lespiau
  6 siblings, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-07-15  8:40 UTC (permalink / raw)
  To: intel-gfx

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

Reset rotation property to 0 wherever applicable

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/drm_fb_helper.c |   10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 3144db9..961afcb 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -345,9 +345,17 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
 
 	drm_warn_on_modeset_not_all_locked(dev);
 
-	list_for_each_entry(plane, &dev->mode_config.plane_list, head)
+	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
+
+		if (dev->mode_config.rotation_property) {
+			drm_object_property_set_value(&plane->base,
+					dev->mode_config.rotation_property,
+					BIT(DRM_ROTATE_0));
+		}
+
 		if (plane->type != DRM_PLANE_TYPE_PRIMARY)
 			drm_plane_force_disable(plane);
+	}
 
 	for (i = 0; i < fb_helper->crtc_count; i++) {
 		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-07-15  8:40 ` [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
@ 2014-07-15  9:11   ` Daniel Vetter
  2014-07-15  9:38     ` Jindal, Sonika
                       ` (3 more replies)
  0 siblings, 4 replies; 58+ messages in thread
From: Daniel Vetter @ 2014-07-15  9:11 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx, Sagar Kamble

On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
> 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>

Some stuff I've noticed below.
-Daniel

> ---
>  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;

We already have helper functions to compute the linear offset properly for
tiling, I think we should put the rotation adjustments in there to avoid
dpulicated code of this. And a comment about how this works would be nice.

> +	}
> +
> +	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 &&

You need to check plane->crtc before upcasting.

> +				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);
> +				}
> +			}

Indentation is screwed up here. Also if we convert some of the checks into
early bails we could de-indent this by one level.

Also Chris mentioned that on some platforms this won't work and it's more
future-proof to just do a full modeset until we have the proper
infrastructure.

> +
> +			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));

The property should be created in
drm_mode_create_standard_plane_properties.

> +		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
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-07-15  9:11   ` 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
                       ` (2 subsequent siblings)
  3 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-07-15  9:38 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx, Sagar Kamble



On 7/15/2014 2:41 PM, Daniel Vetter wrote:
> On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
>> 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>
>
> Some stuff I've noticed below.
> -Daniel
>
>> ---
>>   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;
>
> We already have helper functions to compute the linear offset properly for
> tiling, I think we should put the rotation adjustments in there to avoid
> dpulicated code of this. And a comment about how this works would be nice.
>
Ok, I will add the comments.
>> +	}
>> +
>> +	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 &&
>
> You need to check plane->crtc before upcasting.
>
Ok, I will add.
>> +				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);
>> +				}
>> +			}
>
> Indentation is screwed up here. Also if we convert some of the checks into
> early bails we could de-indent this by one level.
>
Ok, I will add
> Also Chris mentioned that on some platforms this won't work and it's more
> future-proof to just do a full modeset until we have the proper
> infrastructure.
>
Can you please elaborate on this? What needs to be done?

>> +
>> +			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));
>
> The property should be created in
> drm_mode_create_standard_plane_properties.
>
Ok, I will add.

>> +		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
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-07-15  9:38     ` Jindal, Sonika
@ 2014-07-15 10:31       ` Daniel Vetter
  0 siblings, 0 replies; 58+ messages in thread
From: Daniel Vetter @ 2014-07-15 10:31 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx, Sagar Kamble

On Tue, Jul 15, 2014 at 03:08:37PM +0530, Jindal, Sonika wrote:
> On 7/15/2014 2:41 PM, Daniel Vetter wrote:
> >On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
> >>From: Sonika Jindal <sonika.jindal@intel.com>
> Ok, I will add
> >Also Chris mentioned that on some platforms this won't work and it's more
> >future-proof to just do a full modeset until we have the proper
> >infrastructure.
> >
> Can you please elaborate on this? What needs to be done?

Apparently nothing, it turned out that on the platforms currently
supported everything is fine with your patch. Damien promised to follow up
with the details on internal mailing lists.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 0/6] Add 180 degree primary and sprite rotation
  2014-07-15  8:40 [PATCH 0/6] Add 180 degree primary and sprite rotation sonika.jindal
                   ` (5 preceding siblings ...)
  2014-07-15  8:40 ` [PATCH 6/6] drm: Resetting rotation property sonika.jindal
@ 2014-07-15 10:52 ` Damien Lespiau
  2014-07-15 10:55   ` Jindal, Sonika
  6 siblings, 1 reply; 58+ messages in thread
From: Damien Lespiau @ 2014-07-15 10:52 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx

On Tue, Jul 15, 2014 at 02:10:23PM +0530, sonika.jindal@intel.com wrote:
> From: Sonika Jindal <sonika.jindal@intel.com>
> 
> This patchset provides support for 0/180 degree hardare rotaion for primary and
> sprite planes. The rotation property is now made global and is part of
> drm_mode_config. It is attached to different planes.
> 
> Sonika Jindal (3):
>   drm: Add rotation_property to mode_config
>   drm/i915: Add 180 degree primary plane rotation support
>   drm: Resetting rotation property
> 
> Ville Syrjälä (3):
>   drm/i915: Add 180 degree sprite rotation support
>   drm/i915: Make intel_plane_restore() return an error
>   drm/i915: Add rotation property for sprites

Also, you forgot to bump the series version, it's really nice to have it
to follow the progress (and later, to have tools do that for us).

I noticed you likely used --subject-prefix="v3" in the previous one,
that's not quite how one is supposed to do it. The series versioning
goes into the cover letter subject, and that's it.

Cheers,

-- 
Damien

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 0/6] Add 180 degree primary and sprite rotation
  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
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-07-15 10:55 UTC (permalink / raw)
  To: Damien Lespiau; +Cc: intel-gfx



On 7/15/2014 4:22 PM, Damien Lespiau wrote:
> On Tue, Jul 15, 2014 at 02:10:23PM +0530, sonika.jindal@intel.com wrote:
>> From: Sonika Jindal <sonika.jindal@intel.com>
>>
>> This patchset provides support for 0/180 degree hardare rotaion for primary and
>> sprite planes. The rotation property is now made global and is part of
>> drm_mode_config. It is attached to different planes.
>>
>> Sonika Jindal (3):
>>    drm: Add rotation_property to mode_config
>>    drm/i915: Add 180 degree primary plane rotation support
>>    drm: Resetting rotation property
>>
>> Ville Syrjälä (3):
>>    drm/i915: Add 180 degree sprite rotation support
>>    drm/i915: Make intel_plane_restore() return an error
>>    drm/i915: Add rotation property for sprites
>
> Also, you forgot to bump the series version, it's really nice to have it
> to follow the progress (and later, to have tools do that for us).
>
Since this was a new patch set without the previous patches I thought it 
is not needed. Sure I will keep this in mind for the next time.

> I noticed you likely used --subject-prefix="v3" in the previous one,
> that's not quite how one is supposed to do it. The series versioning
> goes into the cover letter subject, and that's it.
>
I was not aware of this. I thought every patch has to have the version 
number. Thanks for pointing it out.
> Cheers,
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 0/6] Add 180 degree primary and sprite rotation
  2014-07-15 10:55   ` Jindal, Sonika
@ 2014-07-15 10:57     ` Damien Lespiau
  0 siblings, 0 replies; 58+ messages in thread
From: Damien Lespiau @ 2014-07-15 10:57 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Tue, Jul 15, 2014 at 04:25:57PM +0530, Jindal, Sonika wrote:
> Since this was a new patch set without the previous patches I
> thought it is not needed. Sure I will keep this in mind for the next
> time.

Ah yes, fair enough, my bad.

-- 
Damien

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 0/3 v2] Moving creation of rotation_property to drm layer
  2014-07-15  9:11   ` Daniel Vetter
  2014-07-15  9:38     ` Jindal, Sonika
@ 2014-07-15 11:30     ` sonika.jindal
  2014-07-15 11:30       ` [PATCH 1/4] drm: Add rotation_property to mode_config and creating it sonika.jindal
                         ` (3 more replies)
  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
  3 siblings, 4 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15 11:30 UTC (permalink / raw)
  To: intel-gfx

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

Incorporating comments from Daniel regarding movement of creation of
rotation_property to drm_mode_create_standard_plane_properties and other minor
things.

Sonika Jindal (3):
  drm: Add rotation_property to mode_config and creating it
  drm/i915: Add 180 degree primary plane rotation support

Ville Syrjälä (1):
  drm/i915: Add rotation property for sprites

 drivers/gpu/drm/drm_crtc.c           |    3 +-
 drivers/gpu/drm/i915/i915_reg.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |  104 ++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_pm.c      |    6 ++
 drivers/gpu/drm/i915/intel_sprite.c  |   35 +++++++++++-
 include/drm/drm_crtc.h               |    1 +
 6 files changed, 153 insertions(+), 7 deletions(-)

-- 
1.7.10.4

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

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 1/4] drm: Add rotation_property to mode_config and creating it
  2014-07-15 11:30     ` [PATCH 0/3 v2] Moving creation of rotation_property to drm layer sonika.jindal
@ 2014-07-15 11:30       ` sonika.jindal
  2014-07-15 11:30       ` [PATCH 2/4] drm/i915: Add rotation property for sprites sonika.jindal
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15 11:30 UTC (permalink / raw)
  To: intel-gfx

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

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/drm_crtc.c |    3 ++-
 include/drm/drm_crtc.h     |    1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 787631e..49c0747 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
 					"type", drm_plane_type_enum_list,
 					ARRAY_SIZE(drm_plane_type_enum_list));
 	dev->mode_config.plane_type_property = type;
-
+	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
+			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
 	return 0;
 }
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index ce6df4a..5545dd3 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -819,6 +819,7 @@ struct drm_mode_config {
 	struct drm_property *dpms_property;
 	struct drm_property *path_property;
 	struct drm_property *plane_type_property;
+	struct drm_property *rotation_property;
 
 	/* DVI-I properties */
 	struct drm_property *dvi_i_subconnector_property;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 2/4] drm/i915: Add rotation property for sprites
  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       ` 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
  3 siblings, 0 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15 11:30 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

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

Sprite planes support 180 degree rotation. The lower layers are now in
place, so hook in the standard rotation property to expose the feature
to the users.

v2: Moving rotation_property to mode_config

v3: Moving creation of property out of intel_sprite

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c |   35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 9fb7523..28c706f 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1218,6 +1218,30 @@ out_unlock:
 	return ret;
 }
 
+static int intel_plane_set_property(struct drm_plane *plane,
+				    struct drm_property *prop,
+				    uint64_t val)
+{
+	struct drm_device *dev = plane->dev;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	uint64_t old_val;
+	int ret = -ENOENT;
+
+	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;
+		ret = intel_plane_restore(plane);
+		if (ret)
+			intel_plane->rotation = old_val;
+	}
+
+	return ret;
+}
+
 int intel_plane_restore(struct drm_plane *plane)
 {
 	struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -1244,6 +1268,7 @@ static const struct drm_plane_funcs intel_plane_funcs = {
 	.update_plane = intel_update_plane,
 	.disable_plane = intel_disable_plane,
 	.destroy = intel_destroy_plane,
+	.set_property = intel_plane_set_property,
 };
 
 static uint32_t ilk_plane_formats[] = {
@@ -1354,8 +1379,16 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 			     &intel_plane_funcs,
 			     plane_formats, num_plane_formats,
 			     false);
-	if (ret)
+	if (ret) {
 		kfree(intel_plane);
+		goto out;
+	}
+
+	if (dev->mode_config.rotation_property)
+		drm_object_attach_property(&intel_plane->base.base,
+					   dev->mode_config.rotation_property,
+					   intel_plane->rotation);
 
+ out:
 	return ret;
 }
-- 
1.7.10.4

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 3/4] drm/i915: Add 180 degree primary plane rotation support
  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       ` sonika.jindal
  2014-07-15 12:02       ` [PATCH 0/3 v2] Moving creation of rotation_property to drm layer Daniel Vetter
  3 siblings, 0 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15 11:30 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sagar Kamble

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.

v10: Moving creation of rotation property out of this file and incorporated
other minor comments from Daniel.

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..0d63f90 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,20 @@ 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);
+
+		/* Finding the last pixel of the last line of the display data and
+		 * adding to linear_offset*/
+		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 +2510,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 +2555,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 +11607,67 @@ 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;
+
+		if (crtc == NULL)
+			return -EINVAL;
+
+		intel_crtc = to_intel_crtc(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, so
+			 * disable it when rotation is not 0 and update it when rotation is
+			 * set back to 0 */
+			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);
+				else if (intel_plane->rotation == 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 +11685,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 +11701,14 @@ 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)
+			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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 0/3 v2] Moving creation of rotation_property to drm layer
  2014-07-15 11:30     ` [PATCH 0/3 v2] Moving creation of rotation_property to drm layer sonika.jindal
                         ` (2 preceding siblings ...)
  2014-07-15 11:30       ` [PATCH 3/4] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
@ 2014-07-15 12:02       ` Daniel Vetter
  2014-07-15 12:10         ` Jindal, Sonika
  3 siblings, 1 reply; 58+ messages in thread
From: Daniel Vetter @ 2014-07-15 12:02 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx

On Tue, Jul 15, 2014 at 05:00:20PM +0530, sonika.jindal@intel.com wrote:
> From: Sonika Jindal <sonika.jindal@intel.com>
> 
> Incorporating comments from Daniel regarding movement of creation of
> rotation_property to drm_mode_create_standard_plane_properties and other minor
> things.
> 
> Sonika Jindal (3):
>   drm: Add rotation_property to mode_config and creating it
>   drm/i915: Add 180 degree primary plane rotation support
> 
> Ville Syrjälä (1):
>   drm/i915: Add rotation property for sprites

The summary says 0/3 but the patches are numbered x/4. That's a bit
confusing. Two fixes:
- Specify the git range for format-patch/send-email with the start..end
  syntax like for git log.
- Send only individual patches in-reply-to the respective original patch.
  This is my preferred approach.

Without that I'll look for 4/4 and won't find it ...

Thanks, Daniel

> 
>  drivers/gpu/drm/drm_crtc.c           |    3 +-
>  drivers/gpu/drm/i915/i915_reg.h      |    1 +
>  drivers/gpu/drm/i915/intel_display.c |  104 ++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_pm.c      |    6 ++
>  drivers/gpu/drm/i915/intel_sprite.c  |   35 +++++++++++-
>  include/drm/drm_crtc.h               |    1 +
>  6 files changed, 153 insertions(+), 7 deletions(-)
> 
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 0/3 v2] Moving creation of rotation_property to drm layer
  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
  0 siblings, 0 replies; 58+ messages in thread
From: Jindal, Sonika @ 2014-07-15 12:10 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx



On 7/15/2014 5:32 PM, Daniel Vetter wrote:
> On Tue, Jul 15, 2014 at 05:00:20PM +0530, sonika.jindal@intel.com wrote:
>> From: Sonika Jindal <sonika.jindal@intel.com>
>>
>> Incorporating comments from Daniel regarding movement of creation of
>> rotation_property to drm_mode_create_standard_plane_properties and other minor
>> things.
>>
>> Sonika Jindal (3):
>>    drm: Add rotation_property to mode_config and creating it
>>    drm/i915: Add 180 degree primary plane rotation support
>>
>> Ville Syrjälä (1):
>>    drm/i915: Add rotation property for sprites
>
> The summary says 0/3 but the patches are numbered x/4. That's a bit
> confusing. Two fixes:
> - Specify the git range for format-patch/send-email with the start..end
>    syntax like for git log.
> - Send only individual patches in-reply-to the respective original patch.
>    This is my preferred approach.
>
Ok, I will send each patch in reply to the original patches. I thought 
replying the affected patches to the comment's mail should make it 
clearer. I'l will send the patches separately.
-Sonika
> Without that I'll look for 4/4 and won't find it ...
>
> Thanks, Daniel
>
>>
>>   drivers/gpu/drm/drm_crtc.c           |    3 +-
>>   drivers/gpu/drm/i915/i915_reg.h      |    1 +
>>   drivers/gpu/drm/i915/intel_display.c |  104 ++++++++++++++++++++++++++++++++--
>>   drivers/gpu/drm/i915/intel_pm.c      |    6 ++
>>   drivers/gpu/drm/i915/intel_sprite.c  |   35 +++++++++++-
>>   include/drm/drm_crtc.h               |    1 +
>>   6 files changed, 153 insertions(+), 7 deletions(-)
>>
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH] drm/i915: Add 180 degree primary plane rotation support
  2014-07-15  9:11   ` Daniel Vetter
  2014-07-15  9:38     ` Jindal, Sonika
  2014-07-15 11:30     ` [PATCH 0/3 v2] Moving creation of rotation_property to drm layer sonika.jindal
@ 2014-07-15 12:10     ` sonika.jindal
  2014-08-07 11:45     ` [PATCH 5/6] " Daniel Vetter
  3 siblings, 0 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15 12:10 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sagar Kamble

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.

v10: Moving creation of rotation property out of this file and incorporated
other minor comments from Daniel.

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..0d63f90 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,20 @@ 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);
+
+		/* Finding the last pixel of the last line of the display data and
+		 * adding to linear_offset*/
+		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 +2510,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 +2555,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 +11607,67 @@ 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;
+
+		if (crtc == NULL)
+			return -EINVAL;
+
+		intel_crtc = to_intel_crtc(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, so
+			 * disable it when rotation is not 0 and update it when rotation is
+			 * set back to 0 */
+			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);
+				else if (intel_plane->rotation == 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 +11685,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 +11701,14 @@ 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)
+			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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH] drm/i915: Add rotation property for sprites
  2014-07-15  8:40 ` [PATCH 4/6] drm/i915: Add rotation property for sprites sonika.jindal
@ 2014-07-15 12:12   ` sonika.jindal
  0 siblings, 0 replies; 58+ messages in thread
From: sonika.jindal @ 2014-07-15 12:12 UTC (permalink / raw)
  To: intel-gfx; +Cc: dri-devel

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

Sprite planes support 180 degree rotation. The lower layers are now in
place, so hook in the standard rotation property to expose the feature
to the users.

v2: Moving rotation_property to mode_config

v3: Moving creation of property out of intel_sprite

Cc: dri-devel@lists.freedesktop.org
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_sprite.c |   35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 9fb7523..28c706f 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1218,6 +1218,30 @@ out_unlock:
 	return ret;
 }
 
+static int intel_plane_set_property(struct drm_plane *plane,
+				    struct drm_property *prop,
+				    uint64_t val)
+{
+	struct drm_device *dev = plane->dev;
+	struct intel_plane *intel_plane = to_intel_plane(plane);
+	uint64_t old_val;
+	int ret = -ENOENT;
+
+	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;
+		ret = intel_plane_restore(plane);
+		if (ret)
+			intel_plane->rotation = old_val;
+	}
+
+	return ret;
+}
+
 int intel_plane_restore(struct drm_plane *plane)
 {
 	struct intel_plane *intel_plane = to_intel_plane(plane);
@@ -1244,6 +1268,7 @@ static const struct drm_plane_funcs intel_plane_funcs = {
 	.update_plane = intel_update_plane,
 	.disable_plane = intel_disable_plane,
 	.destroy = intel_destroy_plane,
+	.set_property = intel_plane_set_property,
 };
 
 static uint32_t ilk_plane_formats[] = {
@@ -1354,8 +1379,16 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
 			     &intel_plane_funcs,
 			     plane_formats, num_plane_formats,
 			     false);
-	if (ret)
+	if (ret) {
 		kfree(intel_plane);
+		goto out;
+	}
+
+	if (dev->mode_config.rotation_property)
+		drm_object_attach_property(&intel_plane->base.base,
+					   dev->mode_config.rotation_property,
+					   intel_plane->rotation);
 
+ out:
 	return ret;
 }
-- 
1.7.10.4

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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH] drm: Add rotation_property to mode_config and creating it
  2014-07-15  8:40 ` [PATCH 3/6] drm: Add rotation_property to mode_config sonika.jindal
@ 2014-07-15 12:13   ` sonika.jindal
  2014-07-28 15:29     ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-07-15 12:13 UTC (permalink / raw)
  To: intel-gfx

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

v2: Adding creation of rotation_property here.

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/drm_crtc.c |    3 ++-
 include/drm/drm_crtc.h     |    1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 787631e..49c0747 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
 					"type", drm_plane_type_enum_list,
 					ARRAY_SIZE(drm_plane_type_enum_list));
 	dev->mode_config.plane_type_property = type;
-
+	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
+			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
 	return 0;
 }
 
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index ce6df4a..5545dd3 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -819,6 +819,7 @@ struct drm_mode_config {
 	struct drm_property *dpms_property;
 	struct drm_property *path_property;
 	struct drm_property *plane_type_property;
+	struct drm_property *rotation_property;
 
 	/* DVI-I properties */
 	struct drm_property *dvi_i_subconnector_property;
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm: Add rotation_property to mode_config and creating it
  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
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2014-07-28 15:29 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx

On Tue, Jul 15, 2014 at 05:43:37PM +0530, sonika.jindal@intel.com wrote:
> From: Sonika Jindal <sonika.jindal@intel.com>
> 
> v2: Adding creation of rotation_property here.
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/drm_crtc.c |    3 ++-
>  include/drm/drm_crtc.h     |    1 +
>  2 files changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> index 787631e..49c0747 100644
> --- a/drivers/gpu/drm/drm_crtc.c
> +++ b/drivers/gpu/drm/drm_crtc.c
> @@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
>  					"type", drm_plane_type_enum_list,
>  					ARRAY_SIZE(drm_plane_type_enum_list));
>  	dev->mode_config.plane_type_property = type;
> -
> +	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
> +			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));

This might not make sense for other (!i915) hardware. And that's the
reason why I had the driver create the property in the first place.

I think Daniel was thinking that we might want to expose all the bits
regardless of what the hardware supports, but I don't like that idea.
There are other properties (eg. alpha blending, csc stuff, etc.) that
have the same problem of hardware supporting only a (potentially small)
subset of the possible values. I'd rather we didn't make life harder
for userspace when the kernel can already report that certain values
will never work.

>  	return 0;
>  }
>  
> diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> index ce6df4a..5545dd3 100644
> --- a/include/drm/drm_crtc.h
> +++ b/include/drm/drm_crtc.h
> @@ -819,6 +819,7 @@ struct drm_mode_config {
>  	struct drm_property *dpms_property;
>  	struct drm_property *path_property;
>  	struct drm_property *plane_type_property;
> +	struct drm_property *rotation_property;
>  
>  	/* DVI-I properties */
>  	struct drm_property *dvi_i_subconnector_property;
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm: Add rotation_property to mode_config and creating it
  2014-07-28 15:29     ` Ville Syrjälä
@ 2014-07-28 18:47       ` Daniel Vetter
  2014-07-29  9:40         ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: Daniel Vetter @ 2014-07-28 18:47 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Mon, Jul 28, 2014 at 06:29:41PM +0300, Ville Syrjälä wrote:
> On Tue, Jul 15, 2014 at 05:43:37PM +0530, sonika.jindal@intel.com wrote:
> > From: Sonika Jindal <sonika.jindal@intel.com>
> > 
> > v2: Adding creation of rotation_property here.
> > 
> > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> > ---
> >  drivers/gpu/drm/drm_crtc.c |    3 ++-
> >  include/drm/drm_crtc.h     |    1 +
> >  2 files changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> > index 787631e..49c0747 100644
> > --- a/drivers/gpu/drm/drm_crtc.c
> > +++ b/drivers/gpu/drm/drm_crtc.c
> > @@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
> >  					"type", drm_plane_type_enum_list,
> >  					ARRAY_SIZE(drm_plane_type_enum_list));
> >  	dev->mode_config.plane_type_property = type;
> > -
> > +	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
> > +			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
> 
> This might not make sense for other (!i915) hardware. And that's the
> reason why I had the driver create the property in the first place.
> 
> I think Daniel was thinking that we might want to expose all the bits
> regardless of what the hardware supports, but I don't like that idea.
> There are other properties (eg. alpha blending, csc stuff, etc.) that
> have the same problem of hardware supporting only a (potentially small)
> subset of the possible values. I'd rather we didn't make life harder
> for userspace when the kernel can already report that certain values
> will never work.

Well I'd like the property to be in some generic place so that fbcon can
unroate and that with the atomic stuff we can have rotation support in the
core structures. Which should help with argument checking.

But for rotation I don't think we should set it up in generic code, but in
i915. So the place where we keep it would be generic, the values would be
the sames, but the allowed set would differ depending upon platform or
driver.
-Daniel

> 
> >  	return 0;
> >  }
> >  
> > diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
> > index ce6df4a..5545dd3 100644
> > --- a/include/drm/drm_crtc.h
> > +++ b/include/drm/drm_crtc.h
> > @@ -819,6 +819,7 @@ struct drm_mode_config {
> >  	struct drm_property *dpms_property;
> >  	struct drm_property *path_property;
> >  	struct drm_property *plane_type_property;
> > +	struct drm_property *rotation_property;
> >  
> >  	/* DVI-I properties */
> >  	struct drm_property *dvi_i_subconnector_property;
> > -- 
> > 1.7.10.4
> > 
> > _______________________________________________
> > Intel-gfx mailing list
> > Intel-gfx@lists.freedesktop.org
> > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> 
> -- 
> Ville Syrjälä
> Intel OTC
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm: Add rotation_property to mode_config and creating it
  2014-07-28 18:47       ` Daniel Vetter
@ 2014-07-29  9:40         ` Ville Syrjälä
  2014-07-29 10:30           ` Daniel Vetter
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2014-07-29  9:40 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx

On Mon, Jul 28, 2014 at 08:47:22PM +0200, Daniel Vetter wrote:
> On Mon, Jul 28, 2014 at 06:29:41PM +0300, Ville Syrjälä wrote:
> > On Tue, Jul 15, 2014 at 05:43:37PM +0530, sonika.jindal@intel.com wrote:
> > > From: Sonika Jindal <sonika.jindal@intel.com>
> > > 
> > > v2: Adding creation of rotation_property here.
> > > 
> > > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> > > ---
> > >  drivers/gpu/drm/drm_crtc.c |    3 ++-
> > >  include/drm/drm_crtc.h     |    1 +
> > >  2 files changed, 3 insertions(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> > > index 787631e..49c0747 100644
> > > --- a/drivers/gpu/drm/drm_crtc.c
> > > +++ b/drivers/gpu/drm/drm_crtc.c
> > > @@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
> > >  					"type", drm_plane_type_enum_list,
> > >  					ARRAY_SIZE(drm_plane_type_enum_list));
> > >  	dev->mode_config.plane_type_property = type;
> > > -
> > > +	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
> > > +			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
> > 
> > This might not make sense for other (!i915) hardware. And that's the
> > reason why I had the driver create the property in the first place.
> > 
> > I think Daniel was thinking that we might want to expose all the bits
> > regardless of what the hardware supports, but I don't like that idea.
> > There are other properties (eg. alpha blending, csc stuff, etc.) that
> > have the same problem of hardware supporting only a (potentially small)
> > subset of the possible values. I'd rather we didn't make life harder
> > for userspace when the kernel can already report that certain values
> > will never work.
> 
> Well I'd like the property to be in some generic place so that fbcon can
> unroate and that with the atomic stuff we can have rotation support in the
> core structures. Which should help with argument checking.
> 
> But for rotation I don't think we should set it up in generic code, but in
> i915. So the place where we keep it would be generic, the values would be
> the sames, but the allowed set would differ depending upon platform or
> driver.

That would still fail if all the planes on the same device don't support
the same rotation flags. Eg. on i915 we would have this problem if we
exposed the old video overlay as a drm plane. And it wouldn't be the
first piece of hardware where I've seen this kind of thing.

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm: Add rotation_property to mode_config and creating it
  2014-07-29  9:40         ` Ville Syrjälä
@ 2014-07-29 10:30           ` Daniel Vetter
  2014-07-31  4:09             ` Jindal, Sonika
  0 siblings, 1 reply; 58+ messages in thread
From: Daniel Vetter @ 2014-07-29 10:30 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx

On Tue, Jul 29, 2014 at 12:40:29PM +0300, Ville Syrjälä wrote:
> On Mon, Jul 28, 2014 at 08:47:22PM +0200, Daniel Vetter wrote:
> > On Mon, Jul 28, 2014 at 06:29:41PM +0300, Ville Syrjälä wrote:
> > > On Tue, Jul 15, 2014 at 05:43:37PM +0530, sonika.jindal@intel.com wrote:
> > > > From: Sonika Jindal <sonika.jindal@intel.com>
> > > > 
> > > > v2: Adding creation of rotation_property here.
> > > > 
> > > > Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> > > > ---
> > > >  drivers/gpu/drm/drm_crtc.c |    3 ++-
> > > >  include/drm/drm_crtc.h     |    1 +
> > > >  2 files changed, 3 insertions(+), 1 deletion(-)
> > > > 
> > > > diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> > > > index 787631e..49c0747 100644
> > > > --- a/drivers/gpu/drm/drm_crtc.c
> > > > +++ b/drivers/gpu/drm/drm_crtc.c
> > > > @@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
> > > >  					"type", drm_plane_type_enum_list,
> > > >  					ARRAY_SIZE(drm_plane_type_enum_list));
> > > >  	dev->mode_config.plane_type_property = type;
> > > > -
> > > > +	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
> > > > +			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
> > > 
> > > This might not make sense for other (!i915) hardware. And that's the
> > > reason why I had the driver create the property in the first place.
> > > 
> > > I think Daniel was thinking that we might want to expose all the bits
> > > regardless of what the hardware supports, but I don't like that idea.
> > > There are other properties (eg. alpha blending, csc stuff, etc.) that
> > > have the same problem of hardware supporting only a (potentially small)
> > > subset of the possible values. I'd rather we didn't make life harder
> > > for userspace when the kernel can already report that certain values
> > > will never work.
> > 
> > Well I'd like the property to be in some generic place so that fbcon can
> > unroate and that with the atomic stuff we can have rotation support in the
> > core structures. Which should help with argument checking.
> > 
> > But for rotation I don't think we should set it up in generic code, but in
> > i915. So the place where we keep it would be generic, the values would be
> > the sames, but the allowed set would differ depending upon platform or
> > driver.
> 
> That would still fail if all the planes on the same device don't support
> the same rotation flags. Eg. on i915 we would have this problem if we
> exposed the old video overlay as a drm plane. And it wouldn't be the
> first piece of hardware where I've seen this kind of thing.

Problem is still that I'd like to have a somewhat generic internal
representation available. We could punt this to atomic though by adding a
rotation field to the drm_plane_state structure. Which is more-or-less my
plan, but wouldn't work with Rob's approach.

Or we keep the property link only in drm_plane (and give drivers the
freedom to set up the underlying enum however they want to), but I'm not
sure whether our interfaces can cope with that.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm: Add rotation_property to mode_config and creating it
  2014-07-29 10:30           ` Daniel Vetter
@ 2014-07-31  4:09             ` Jindal, Sonika
  2014-08-04 10:29               ` Jindal, Sonika
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-07-31  4:09 UTC (permalink / raw)
  To: Daniel Vetter, Ville Syrjälä; +Cc: intel-gfx



On 7/29/2014 4:00 PM, Daniel Vetter wrote:
> On Tue, Jul 29, 2014 at 12:40:29PM +0300, Ville Syrjälä wrote:
>> On Mon, Jul 28, 2014 at 08:47:22PM +0200, Daniel Vetter wrote:
>>> On Mon, Jul 28, 2014 at 06:29:41PM +0300, Ville Syrjälä wrote:
>>>> On Tue, Jul 15, 2014 at 05:43:37PM +0530, sonika.jindal@intel.com wrote:
>>>>> From: Sonika Jindal <sonika.jindal@intel.com>
>>>>>
>>>>> v2: Adding creation of rotation_property here.
>>>>>
>>>>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>>>>> ---
>>>>>   drivers/gpu/drm/drm_crtc.c |    3 ++-
>>>>>   include/drm/drm_crtc.h     |    1 +
>>>>>   2 files changed, 3 insertions(+), 1 deletion(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>>>>> index 787631e..49c0747 100644
>>>>> --- a/drivers/gpu/drm/drm_crtc.c
>>>>> +++ b/drivers/gpu/drm/drm_crtc.c
>>>>> @@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
>>>>>   					"type", drm_plane_type_enum_list,
>>>>>   					ARRAY_SIZE(drm_plane_type_enum_list));
>>>>>   	dev->mode_config.plane_type_property = type;
>>>>> -
>>>>> +	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
>>>>> +			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
>>>>
>>>> This might not make sense for other (!i915) hardware. And that's the
>>>> reason why I had the driver create the property in the first place.
>>>>
>>>> I think Daniel was thinking that we might want to expose all the bits
>>>> regardless of what the hardware supports, but I don't like that idea.
>>>> There are other properties (eg. alpha blending, csc stuff, etc.) that
>>>> have the same problem of hardware supporting only a (potentially small)
>>>> subset of the possible values. I'd rather we didn't make life harder
>>>> for userspace when the kernel can already report that certain values
>>>> will never work.
>>>
>>> Well I'd like the property to be in some generic place so that fbcon can
>>> unroate and that with the atomic stuff we can have rotation support in the
>>> core structures. Which should help with argument checking.
>>>
>>> But for rotation I don't think we should set it up in generic code, but in
>>> i915. So the place where we keep it would be generic, the values would be
>>> the sames, but the allowed set would differ depending upon platform or
>>> driver.
>>
>> That would still fail if all the planes on the same device don't support
>> the same rotation flags. Eg. on i915 we would have this problem if we
>> exposed the old video overlay as a drm plane. And it wouldn't be the
>> first piece of hardware where I've seen this kind of thing.
>
> Problem is still that I'd like to have a somewhat generic internal
> representation available. We could punt this to atomic though by adding a
> rotation field to the drm_plane_state structure. Which is more-or-less my
> plan, but wouldn't work with Rob's approach.
>
> Or we keep the property link only in drm_plane (and give drivers the
> freedom to set up the underlying enum however they want to), but I'm not
> sure whether our interfaces can cope with that.
> -Daniel
>
Daniel, Ville

So what is the suggestion for this property? Should I be moving it to 
somewhere else?

-Sonika

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm: Add rotation_property to mode_config and creating it
  2014-07-31  4:09             ` Jindal, Sonika
@ 2014-08-04 10:29               ` Jindal, Sonika
  2014-08-04 11:54                 ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-04 10:29 UTC (permalink / raw)
  To: Daniel Vetter, Ville Syrjälä; +Cc: intel-gfx



On 7/31/2014 9:39 AM, Jindal, Sonika wrote:
>
>
> On 7/29/2014 4:00 PM, Daniel Vetter wrote:
>> On Tue, Jul 29, 2014 at 12:40:29PM +0300, Ville Syrjälä wrote:
>>> On Mon, Jul 28, 2014 at 08:47:22PM +0200, Daniel Vetter wrote:
>>>> On Mon, Jul 28, 2014 at 06:29:41PM +0300, Ville Syrjälä wrote:
>>>>> On Tue, Jul 15, 2014 at 05:43:37PM +0530, sonika.jindal@intel.com wrote:
>>>>>> From: Sonika Jindal <sonika.jindal@intel.com>
>>>>>>
>>>>>> v2: Adding creation of rotation_property here.
>>>>>>
>>>>>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>>>>>> ---
>>>>>>    drivers/gpu/drm/drm_crtc.c |    3 ++-
>>>>>>    include/drm/drm_crtc.h     |    1 +
>>>>>>    2 files changed, 3 insertions(+), 1 deletion(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>>>>>> index 787631e..49c0747 100644
>>>>>> --- a/drivers/gpu/drm/drm_crtc.c
>>>>>> +++ b/drivers/gpu/drm/drm_crtc.c
>>>>>> @@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
>>>>>>    					"type", drm_plane_type_enum_list,
>>>>>>    					ARRAY_SIZE(drm_plane_type_enum_list));
>>>>>>    	dev->mode_config.plane_type_property = type;
>>>>>> -
>>>>>> +	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
>>>>>> +			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
>>>>>
>>>>> This might not make sense for other (!i915) hardware. And that's the
>>>>> reason why I had the driver create the property in the first place.
>>>>>
>>>>> I think Daniel was thinking that we might want to expose all the bits
>>>>> regardless of what the hardware supports, but I don't like that idea.
>>>>> There are other properties (eg. alpha blending, csc stuff, etc.) that
>>>>> have the same problem of hardware supporting only a (potentially small)
>>>>> subset of the possible values. I'd rather we didn't make life harder
>>>>> for userspace when the kernel can already report that certain values
>>>>> will never work.
>>>>
>>>> Well I'd like the property to be in some generic place so that fbcon can
>>>> unroate and that with the atomic stuff we can have rotation support in the
>>>> core structures. Which should help with argument checking.
>>>>
>>>> But for rotation I don't think we should set it up in generic code, but in
>>>> i915. So the place where we keep it would be generic, the values would be
>>>> the sames, but the allowed set would differ depending upon platform or
>>>> driver.
>>>
>>> That would still fail if all the planes on the same device don't support
>>> the same rotation flags. Eg. on i915 we would have this problem if we
>>> exposed the old video overlay as a drm plane. And it wouldn't be the
>>> first piece of hardware where I've seen this kind of thing.
>>
>> Problem is still that I'd like to have a somewhat generic internal
>> representation available. We could punt this to atomic though by adding a
>> rotation field to the drm_plane_state structure. Which is more-or-less my
>> plan, but wouldn't work with Rob's approach.
>>
>> Or we keep the property link only in drm_plane (and give drivers the
>> freedom to set up the underlying enum however they want to), but I'm not
>> sure whether our interfaces can cope with that.
>> -Daniel
>>
> Daniel, Ville
>
> So what is the suggestion for this property? Should I be moving it to
> somewhere else?
>
> -Sonika
Hi Daniel/Ville,

Please let me know if I need to move this property somewhere else.

Thanks,
Sonika
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm: Add rotation_property to mode_config and creating it
  2014-08-04 10:29               ` Jindal, Sonika
@ 2014-08-04 11:54                 ` Ville Syrjälä
  2014-08-04 12:04                   ` Jindal, Sonika
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2014-08-04 11:54 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx

On Mon, Aug 04, 2014 at 03:59:23PM +0530, Jindal, Sonika wrote:
> 
> 
> On 7/31/2014 9:39 AM, Jindal, Sonika wrote:
> >
> >
> > On 7/29/2014 4:00 PM, Daniel Vetter wrote:
> >> On Tue, Jul 29, 2014 at 12:40:29PM +0300, Ville Syrjälä wrote:
> >>> On Mon, Jul 28, 2014 at 08:47:22PM +0200, Daniel Vetter wrote:
> >>>> On Mon, Jul 28, 2014 at 06:29:41PM +0300, Ville Syrjälä wrote:
> >>>>> On Tue, Jul 15, 2014 at 05:43:37PM +0530, sonika.jindal@intel.com wrote:
> >>>>>> From: Sonika Jindal <sonika.jindal@intel.com>
> >>>>>>
> >>>>>> v2: Adding creation of rotation_property here.
> >>>>>>
> >>>>>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> >>>>>> ---
> >>>>>>    drivers/gpu/drm/drm_crtc.c |    3 ++-
> >>>>>>    include/drm/drm_crtc.h     |    1 +
> >>>>>>    2 files changed, 3 insertions(+), 1 deletion(-)
> >>>>>>
> >>>>>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
> >>>>>> index 787631e..49c0747 100644
> >>>>>> --- a/drivers/gpu/drm/drm_crtc.c
> >>>>>> +++ b/drivers/gpu/drm/drm_crtc.c
> >>>>>> @@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
> >>>>>>    					"type", drm_plane_type_enum_list,
> >>>>>>    					ARRAY_SIZE(drm_plane_type_enum_list));
> >>>>>>    	dev->mode_config.plane_type_property = type;
> >>>>>> -
> >>>>>> +	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
> >>>>>> +			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
> >>>>>
> >>>>> This might not make sense for other (!i915) hardware. And that's the
> >>>>> reason why I had the driver create the property in the first place.
> >>>>>
> >>>>> I think Daniel was thinking that we might want to expose all the bits
> >>>>> regardless of what the hardware supports, but I don't like that idea.
> >>>>> There are other properties (eg. alpha blending, csc stuff, etc.) that
> >>>>> have the same problem of hardware supporting only a (potentially small)
> >>>>> subset of the possible values. I'd rather we didn't make life harder
> >>>>> for userspace when the kernel can already report that certain values
> >>>>> will never work.
> >>>>
> >>>> Well I'd like the property to be in some generic place so that fbcon can
> >>>> unroate and that with the atomic stuff we can have rotation support in the
> >>>> core structures. Which should help with argument checking.
> >>>>
> >>>> But for rotation I don't think we should set it up in generic code, but in
> >>>> i915. So the place where we keep it would be generic, the values would be
> >>>> the sames, but the allowed set would differ depending upon platform or
> >>>> driver.
> >>>
> >>> That would still fail if all the planes on the same device don't support
> >>> the same rotation flags. Eg. on i915 we would have this problem if we
> >>> exposed the old video overlay as a drm plane. And it wouldn't be the
> >>> first piece of hardware where I've seen this kind of thing.
> >>
> >> Problem is still that I'd like to have a somewhat generic internal
> >> representation available. We could punt this to atomic though by adding a
> >> rotation field to the drm_plane_state structure. Which is more-or-less my
> >> plan, but wouldn't work with Rob's approach.
> >>
> >> Or we keep the property link only in drm_plane (and give drivers the
> >> freedom to set up the underlying enum however they want to), but I'm not
> >> sure whether our interfaces can cope with that.
> >> -Daniel
> >>
> > Daniel, Ville
> >
> > So what is the suggestion for this property? Should I be moving it to
> > somewhere else?
> >
> > -Sonika
> Hi Daniel/Ville,
> 
> Please let me know if I need to move this property somewhere else.

Well we at least need to move the crationg of the property to the
driver. I guess we could leave the property itself in place in
mode_config so that fbdev can get at it easily. If we come across
a real need for separate per-plane rotation properties we can always
move it to drm_plane later.

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 6/6] drm: Resetting rotation property
  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
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2014-08-04 12:01 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx

On Tue, Jul 15, 2014 at 02:10:29PM +0530, sonika.jindal@intel.com wrote:
> From: Sonika Jindal <sonika.jindal@intel.com>
> 
> Reset rotation property to 0 wherever applicable
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/drm_fb_helper.c |   10 +++++++++-
>  1 file changed, 9 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
> index 3144db9..961afcb 100644
> --- a/drivers/gpu/drm/drm_fb_helper.c
> +++ b/drivers/gpu/drm/drm_fb_helper.c
> @@ -345,9 +345,17 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
>  
>  	drm_warn_on_modeset_not_all_locked(dev);
>  
> -	list_for_each_entry(plane, &dev->mode_config.plane_list, head)
> +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
> +
> +		if (dev->mode_config.rotation_property) {
> +			drm_object_property_set_value(&plane->base,
> +					dev->mode_config.rotation_property,
> +					BIT(DRM_ROTATE_0));
> +		}
> +
>  		if (plane->type != DRM_PLANE_TYPE_PRIMARY)
>  			drm_plane_force_disable(plane);

I would reset the property after disabling the plane.

> +	}
>  
>  	for (i = 0; i < fb_helper->crtc_count; i++) {
>  		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 6/6] drm: Resetting rotation property
  2014-08-04 12:01   ` Ville Syrjälä
@ 2014-08-04 12:03     ` Jindal, Sonika
  0 siblings, 0 replies; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-04 12:03 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx



On 8/4/2014 5:31 PM, Ville Syrjälä wrote:
> On Tue, Jul 15, 2014 at 02:10:29PM +0530, sonika.jindal@intel.com wrote:
>> From: Sonika Jindal <sonika.jindal@intel.com>
>>
>> Reset rotation property to 0 wherever applicable
>>
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>> ---
>>   drivers/gpu/drm/drm_fb_helper.c |   10 +++++++++-
>>   1 file changed, 9 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
>> index 3144db9..961afcb 100644
>> --- a/drivers/gpu/drm/drm_fb_helper.c
>> +++ b/drivers/gpu/drm/drm_fb_helper.c
>> @@ -345,9 +345,17 @@ static bool restore_fbdev_mode(struct drm_fb_helper *fb_helper)
>>
>>   	drm_warn_on_modeset_not_all_locked(dev);
>>
>> -	list_for_each_entry(plane, &dev->mode_config.plane_list, head)
>> +	list_for_each_entry(plane, &dev->mode_config.plane_list, head) {
>> +
>> +		if (dev->mode_config.rotation_property) {
>> +			drm_object_property_set_value(&plane->base,
>> +					dev->mode_config.rotation_property,
>> +					BIT(DRM_ROTATE_0));
>> +		}
>> +
>>   		if (plane->type != DRM_PLANE_TYPE_PRIMARY)
>>   			drm_plane_force_disable(plane);
>
> I would reset the property after disabling the plane.
Ok, I will change that.
>
>> +	}
>>
>>   	for (i = 0; i < fb_helper->crtc_count; i++) {
>>   		struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm: Add rotation_property to mode_config and creating it
  2014-08-04 11:54                 ` Ville Syrjälä
@ 2014-08-04 12:04                   ` Jindal, Sonika
  0 siblings, 0 replies; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-04 12:04 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx



On 8/4/2014 5:24 PM, Ville Syrjälä wrote:
> On Mon, Aug 04, 2014 at 03:59:23PM +0530, Jindal, Sonika wrote:
>>
>>
>> On 7/31/2014 9:39 AM, Jindal, Sonika wrote:
>>>
>>>
>>> On 7/29/2014 4:00 PM, Daniel Vetter wrote:
>>>> On Tue, Jul 29, 2014 at 12:40:29PM +0300, Ville Syrjälä wrote:
>>>>> On Mon, Jul 28, 2014 at 08:47:22PM +0200, Daniel Vetter wrote:
>>>>>> On Mon, Jul 28, 2014 at 06:29:41PM +0300, Ville Syrjälä wrote:
>>>>>>> On Tue, Jul 15, 2014 at 05:43:37PM +0530, sonika.jindal@intel.com wrote:
>>>>>>>> From: Sonika Jindal <sonika.jindal@intel.com>
>>>>>>>>
>>>>>>>> v2: Adding creation of rotation_property here.
>>>>>>>>
>>>>>>>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>>>>>>>> ---
>>>>>>>>     drivers/gpu/drm/drm_crtc.c |    3 ++-
>>>>>>>>     include/drm/drm_crtc.h     |    1 +
>>>>>>>>     2 files changed, 3 insertions(+), 1 deletion(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
>>>>>>>> index 787631e..49c0747 100644
>>>>>>>> --- a/drivers/gpu/drm/drm_crtc.c
>>>>>>>> +++ b/drivers/gpu/drm/drm_crtc.c
>>>>>>>> @@ -1299,7 +1299,8 @@ static int drm_mode_create_standard_plane_properties(struct drm_device *dev)
>>>>>>>>     					"type", drm_plane_type_enum_list,
>>>>>>>>     					ARRAY_SIZE(drm_plane_type_enum_list));
>>>>>>>>     	dev->mode_config.plane_type_property = type;
>>>>>>>> -
>>>>>>>> +	dev->mode_config.rotation_property = drm_mode_create_rotation_property(dev,
>>>>>>>> +			BIT(DRM_ROTATE_0) | BIT(DRM_ROTATE_180));
>>>>>>>
>>>>>>> This might not make sense for other (!i915) hardware. And that's the
>>>>>>> reason why I had the driver create the property in the first place.
>>>>>>>
>>>>>>> I think Daniel was thinking that we might want to expose all the bits
>>>>>>> regardless of what the hardware supports, but I don't like that idea.
>>>>>>> There are other properties (eg. alpha blending, csc stuff, etc.) that
>>>>>>> have the same problem of hardware supporting only a (potentially small)
>>>>>>> subset of the possible values. I'd rather we didn't make life harder
>>>>>>> for userspace when the kernel can already report that certain values
>>>>>>> will never work.
>>>>>>
>>>>>> Well I'd like the property to be in some generic place so that fbcon can
>>>>>> unroate and that with the atomic stuff we can have rotation support in the
>>>>>> core structures. Which should help with argument checking.
>>>>>>
>>>>>> But for rotation I don't think we should set it up in generic code, but in
>>>>>> i915. So the place where we keep it would be generic, the values would be
>>>>>> the sames, but the allowed set would differ depending upon platform or
>>>>>> driver.
>>>>>
>>>>> That would still fail if all the planes on the same device don't support
>>>>> the same rotation flags. Eg. on i915 we would have this problem if we
>>>>> exposed the old video overlay as a drm plane. And it wouldn't be the
>>>>> first piece of hardware where I've seen this kind of thing.
>>>>
>>>> Problem is still that I'd like to have a somewhat generic internal
>>>> representation available. We could punt this to atomic though by adding a
>>>> rotation field to the drm_plane_state structure. Which is more-or-less my
>>>> plan, but wouldn't work with Rob's approach.
>>>>
>>>> Or we keep the property link only in drm_plane (and give drivers the
>>>> freedom to set up the underlying enum however they want to), but I'm not
>>>> sure whether our interfaces can cope with that.
>>>> -Daniel
>>>>
>>> Daniel, Ville
>>>
>>> So what is the suggestion for this property? Should I be moving it to
>>> somewhere else?
>>>
>>> -Sonika
>> Hi Daniel/Ville,
>>
>> Please let me know if I need to move this property somewhere else.
>
> Well we at least need to move the crationg of the property to the
> driver. I guess we could leave the property itself in place in
> mode_config so that fbdev can get at it easily. If we come across
> a real need for separate per-plane rotation properties we can always
> move it to drm_plane later.
>
Ok, I will move it back to plane_create function.

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-07-15  9:11   ` Daniel Vetter
                       ` (2 preceding siblings ...)
  2014-07-15 12:10     ` [PATCH] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
@ 2014-08-07 11:45     ` Daniel Vetter
  2014-08-07 12:11       ` Daniel Vetter
  3 siblings, 1 reply; 58+ messages in thread
From: Daniel Vetter @ 2014-08-07 11:45 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx, Sagar Kamble

On Tue, Jul 15, 2014 at 11:11:37AM +0200, Daniel Vetter wrote:
> On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
> > +		/* 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);
> > +				}
> > +			}
> 
> Indentation is screwed up here. Also if we convert some of the checks into
> early bails we could de-indent this by one level.
> 
> Also Chris mentioned that on some platforms this won't work and it's more
> future-proof to just do a full modeset until we have the proper
> infrastructure.

Apparently this review here was never addressed, as Chris just pointed out
on irc. I've dropped the patch again.

I think we need:
- The same sequence as with the sprite set_property function, i.e. we need
  to call the update_plane function (not the raw low-level one, the
  high-level with all the checks).
- The fbc check is wrong and will miss updates when the crtc is off. We
  need to move this into the general list of checks in intel_update_fbc.
- Since this seems to be buggy I want added testcases to combine fbc
  correctness with screen rotation. Probably best to reuse the existing
  fbc testcase and add a bunch or rotated tests.

Thanks, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-08-07 11:45     ` [PATCH 5/6] " Daniel Vetter
@ 2014-08-07 12:11       ` Daniel Vetter
  2014-08-11 11:07         ` Jindal, Sonika
  0 siblings, 1 reply; 58+ messages in thread
From: Daniel Vetter @ 2014-08-07 12:11 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx, Sagar Kamble

On Thu, Aug 07, 2014 at 01:45:31PM +0200, Daniel Vetter wrote:
> On Tue, Jul 15, 2014 at 11:11:37AM +0200, Daniel Vetter wrote:
> > On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
> > > +		/* 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);
> > > +				}
> > > +			}
> > 
> > Indentation is screwed up here. Also if we convert some of the checks into
> > early bails we could de-indent this by one level.
> > 
> > Also Chris mentioned that on some platforms this won't work and it's more
> > future-proof to just do a full modeset until we have the proper
> > infrastructure.
> 
> Apparently this review here was never addressed, as Chris just pointed out
> on irc. I've dropped the patch again.
> 
> I think we need:
> - The same sequence as with the sprite set_property function, i.e. we need
>   to call the update_plane function (not the raw low-level one, the
>   high-level with all the checks).
> - The fbc check is wrong and will miss updates when the crtc is off. We
>   need to move this into the general list of checks in intel_update_fbc.
> - Since this seems to be buggy I want added testcases to combine fbc
>   correctness with screen rotation. Probably best to reuse the existing
>   fbc testcase and add a bunch or rotated tests.

Ok, the check in update_fbc is there, I've been blind. Sorry about all the
confusion. So just amounts of calling the higher level function and we can
forgo the fbc testing.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-08-07 12:11       ` Daniel Vetter
@ 2014-08-11 11:07         ` Jindal, Sonika
  2014-08-11 11:42           ` Daniel Vetter
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-11 11:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx, Sagar Kamble


Hi Daniel,
Are you taking this patch back in drm-intel?

-Sonika

On 8/7/2014 5:41 PM, Daniel Vetter wrote:
> On Thu, Aug 07, 2014 at 01:45:31PM +0200, Daniel Vetter wrote:
>> On Tue, Jul 15, 2014 at 11:11:37AM +0200, Daniel Vetter wrote:
>>> On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
>>>> +		/* 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);
>>>> +				}
>>>> +			}
>>>
>>> Indentation is screwed up here. Also if we convert some of the checks into
>>> early bails we could de-indent this by one level.
>>>
>>> Also Chris mentioned that on some platforms this won't work and it's more
>>> future-proof to just do a full modeset until we have the proper
>>> infrastructure.
>>
>> Apparently this review here was never addressed, as Chris just pointed out
>> on irc. I've dropped the patch again.
>>
>> I think we need:
>> - The same sequence as with the sprite set_property function, i.e. we need
>>    to call the update_plane function (not the raw low-level one, the
>>    high-level with all the checks).
>> - The fbc check is wrong and will miss updates when the crtc is off. We
>>    need to move this into the general list of checks in intel_update_fbc.
>> - Since this seems to be buggy I want added testcases to combine fbc
>>    correctness with screen rotation. Probably best to reuse the existing
>>    fbc testcase and add a bunch or rotated tests.
>
> Ok, the check in update_fbc is there, I've been blind. Sorry about all the
> confusion. So just amounts of calling the higher level function and we can
> forgo the fbc testing.
> -Daniel
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-08-11 11:07         ` Jindal, Sonika
@ 2014-08-11 11:42           ` Daniel Vetter
  2014-08-11 12:07             ` Jindal, Sonika
  0 siblings, 1 reply; 58+ messages in thread
From: Daniel Vetter @ 2014-08-11 11:42 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx, Sagar Kamble

On Mon, Aug 11, 2014 at 04:37:00PM +0530, Jindal, Sonika wrote:
> 
> Hi Daniel,
> Are you taking this patch back in drm-intel?

We should still call the primary_plane->update hook directly instead of
open-coding it.
-Daniel

> 
> -Sonika
> 
> On 8/7/2014 5:41 PM, Daniel Vetter wrote:
> >On Thu, Aug 07, 2014 at 01:45:31PM +0200, Daniel Vetter wrote:
> >>On Tue, Jul 15, 2014 at 11:11:37AM +0200, Daniel Vetter wrote:
> >>>On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
> >>>>+		/* 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);
> >>>>+				}
> >>>>+			}
> >>>
> >>>Indentation is screwed up here. Also if we convert some of the checks into
> >>>early bails we could de-indent this by one level.
> >>>
> >>>Also Chris mentioned that on some platforms this won't work and it's more
> >>>future-proof to just do a full modeset until we have the proper
> >>>infrastructure.
> >>
> >>Apparently this review here was never addressed, as Chris just pointed out
> >>on irc. I've dropped the patch again.
> >>
> >>I think we need:
> >>- The same sequence as with the sprite set_property function, i.e. we need
> >>   to call the update_plane function (not the raw low-level one, the
> >>   high-level with all the checks).
> >>- The fbc check is wrong and will miss updates when the crtc is off. We
> >>   need to move this into the general list of checks in intel_update_fbc.
> >>- Since this seems to be buggy I want added testcases to combine fbc
> >>   correctness with screen rotation. Probably best to reuse the existing
> >>   fbc testcase and add a bunch or rotated tests.
> >
> >Ok, the check in update_fbc is there, I've been blind. Sorry about all the
> >confusion. So just amounts of calling the higher level function and we can
> >forgo the fbc testing.
> >-Daniel
> >

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-08-11 11:42           ` Daniel Vetter
@ 2014-08-11 12:07             ` Jindal, Sonika
  2014-08-11 12:23               ` Daniel Vetter
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-11 12:07 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx, Sagar Kamble



On 8/11/2014 5:12 PM, Daniel Vetter wrote:
> On Mon, Aug 11, 2014 at 04:37:00PM +0530, Jindal, Sonika wrote:
>>
>> Hi Daniel,
>> Are you taking this patch back in drm-intel?
>
> We should still call the primary_plane->update hook directly instead of
> open-coding it.
> -Daniel
>
But we are already doing dev_priv->display.update_primary_plane. Can you 
please elaborate? Last time we had a discussion on this same point, and 
we thought for some platforms more work might be needed but for current 
platforms this looks ok. Following was the discussion:

"> >Also Chris mentioned that on some platforms this won't work and it's
 > >more future-proof to just do a full modeset until we have the proper
 > >infrastructure.
 > >
 > Can you please elaborate on this? What needs to be done?

Apparently nothing, it turned out that on the platforms currently 
supported everything is fine with your patch. Damien promised to follow 
up with the details on internal mailing lists.
-Daniel
"

>>
>> -Sonika
>>
>> On 8/7/2014 5:41 PM, Daniel Vetter wrote:
>>> On Thu, Aug 07, 2014 at 01:45:31PM +0200, Daniel Vetter wrote:
>>>> On Tue, Jul 15, 2014 at 11:11:37AM +0200, Daniel Vetter wrote:
>>>>> On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
>>>>>> +		/* 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);
>>>>>> +				}
>>>>>> +			}
>>>>>
>>>>> Indentation is screwed up here. Also if we convert some of the checks into
>>>>> early bails we could de-indent this by one level.
>>>>>
>>>>> Also Chris mentioned that on some platforms this won't work and it's more
>>>>> future-proof to just do a full modeset until we have the proper
>>>>> infrastructure.
>>>>
>>>> Apparently this review here was never addressed, as Chris just pointed out
>>>> on irc. I've dropped the patch again.
>>>>
>>>> I think we need:
>>>> - The same sequence as with the sprite set_property function, i.e. we need
>>>>    to call the update_plane function (not the raw low-level one, the
>>>>    high-level with all the checks).
>>>> - The fbc check is wrong and will miss updates when the crtc is off. We
>>>>    need to move this into the general list of checks in intel_update_fbc.
>>>> - Since this seems to be buggy I want added testcases to combine fbc
>>>>    correctness with screen rotation. Probably best to reuse the existing
>>>>    fbc testcase and add a bunch or rotated tests.
>>>
>>> Ok, the check in update_fbc is there, I've been blind. Sorry about all the
>>> confusion. So just amounts of calling the higher level function and we can
>>> forgo the fbc testing.
>>> -Daniel
>>>
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  2014-08-11 12:07             ` Jindal, Sonika
@ 2014-08-11 12:23               ` Daniel Vetter
  2014-08-12  3:25                 ` Jindal, Sonika
  0 siblings, 1 reply; 58+ messages in thread
From: Daniel Vetter @ 2014-08-11 12:23 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx, Sagar Kamble

On Mon, Aug 11, 2014 at 05:37:20PM +0530, Jindal, Sonika wrote:
> 
> 
> On 8/11/2014 5:12 PM, Daniel Vetter wrote:
> >On Mon, Aug 11, 2014 at 04:37:00PM +0530, Jindal, Sonika wrote:
> >>
> >>Hi Daniel,
> >>Are you taking this patch back in drm-intel?
> >
> >We should still call the primary_plane->update hook directly instead of
> >open-coding it.
> >-Daniel
> >
> But we are already doing dev_priv->display.update_primary_plane. Can you
> please elaborate? Last time we had a discussion on this same point, and we
> thought for some platforms more work might be needed but for current
> platforms this looks ok. Following was the discussion:

That's a different cook used internally in the driver (mostly for
historical reasons nowadays). I'm talking about the
drm_plane->fops->update_plane hook, which is implemented for primary
planes by intel_primary_plane_setplane.

The idea is to have the exact same code flow as for sprite planes, since
once we have atomic modesets that will be what we need. In the sprite
set_prop function you pretty directly call the update_plane hook, and I
think we should do the same here. Actually we might as well directly reuse
the intel_plane_restore function, it seems to exactly do what we want.

> "> >Also Chris mentioned that on some platforms this won't work and it's
> > >more future-proof to just do a full modeset until we have the proper
> > >infrastructure.
> > >
> > Can you please elaborate on this? What needs to be done?
> 
> Apparently nothing, it turned out that on the platforms currently supported
> everything is fine with your patch. Damien promised to follow up with the
> details on internal mailing lists.

Damien follow up internally. Since we're now allowed to talk about skl
I'll paste this here:

"On SKL, for 90/270, we'll also need to update the watermarks and remap
the fb.

"We already duplicate some of the logic: the FBC update, wait for
pending flips, ...

"So maybe we should try to find a way to take the same path for all
updates. I'm not too sure how practical this is though."

Damien also said that he doesn't want to still the series on this, but
since we now have universal plane support for the primary plane I think it
makes a lot of sense.
-Daniel


> -Daniel
> "
> 
> >>
> >>-Sonika
> >>
> >>On 8/7/2014 5:41 PM, Daniel Vetter wrote:
> >>>On Thu, Aug 07, 2014 at 01:45:31PM +0200, Daniel Vetter wrote:
> >>>>On Tue, Jul 15, 2014 at 11:11:37AM +0200, Daniel Vetter wrote:
> >>>>>On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
> >>>>>>+		/* 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);
> >>>>>>+				}
> >>>>>>+			}
> >>>>>
> >>>>>Indentation is screwed up here. Also if we convert some of the checks into
> >>>>>early bails we could de-indent this by one level.
> >>>>>
> >>>>>Also Chris mentioned that on some platforms this won't work and it's more
> >>>>>future-proof to just do a full modeset until we have the proper
> >>>>>infrastructure.
> >>>>
> >>>>Apparently this review here was never addressed, as Chris just pointed out
> >>>>on irc. I've dropped the patch again.
> >>>>
> >>>>I think we need:
> >>>>- The same sequence as with the sprite set_property function, i.e. we need
> >>>>   to call the update_plane function (not the raw low-level one, the
> >>>>   high-level with all the checks).
> >>>>- The fbc check is wrong and will miss updates when the crtc is off. We
> >>>>   need to move this into the general list of checks in intel_update_fbc.
> >>>>- Since this seems to be buggy I want added testcases to combine fbc
> >>>>   correctness with screen rotation. Probably best to reuse the existing
> >>>>   fbc testcase and add a bunch or rotated tests.
> >>>
> >>>Ok, the check in update_fbc is there, I've been blind. Sorry about all the
> >>>confusion. So just amounts of calling the higher level function and we can
> >>>forgo the fbc testing.
> >>>-Daniel
> >>>
> >

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support
  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
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-12  3:25 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx, Sagar Kamble



On 8/11/2014 5:53 PM, Daniel Vetter wrote:
> On Mon, Aug 11, 2014 at 05:37:20PM +0530, Jindal, Sonika wrote:
>>
>>
>> On 8/11/2014 5:12 PM, Daniel Vetter wrote:
>>> On Mon, Aug 11, 2014 at 04:37:00PM +0530, Jindal, Sonika wrote:
>>>>
>>>> Hi Daniel,
>>>> Are you taking this patch back in drm-intel?
>>>
>>> We should still call the primary_plane->update hook directly instead of
>>> open-coding it.
>>> -Daniel
>>>
>> But we are already doing dev_priv->display.update_primary_plane. Can you
>> please elaborate? Last time we had a discussion on this same point, and we
>> thought for some platforms more work might be needed but for current
>> platforms this looks ok. Following was the discussion:
>
> That's a different cook used internally in the driver (mostly for
> historical reasons nowadays). I'm talking about the
> drm_plane->fops->update_plane hook, which is implemented for primary
> planes by intel_primary_plane_setplane.
>
Ok, let me add that and post a new patch for this.

-Sonika
> The idea is to have the exact same code flow as for sprite planes, since
> once we have atomic modesets that will be what we need. In the sprite
> set_prop function you pretty directly call the update_plane hook, and I
> think we should do the same here. Actually we might as well directly reuse
> the intel_plane_restore function, it seems to exactly do what we want.
>
>> "> >Also Chris mentioned that on some platforms this won't work and it's
>>>> more future-proof to just do a full modeset until we have the proper
>>>> infrastructure.
>>>>
>>> Can you please elaborate on this? What needs to be done?
>>
>> Apparently nothing, it turned out that on the platforms currently supported
>> everything is fine with your patch. Damien promised to follow up with the
>> details on internal mailing lists.
>
> Damien follow up internally. Since we're now allowed to talk about skl
> I'll paste this here:
>
> "On SKL, for 90/270, we'll also need to update the watermarks and remap
> the fb.
>
> "We already duplicate some of the logic: the FBC update, wait for
> pending flips, ...
>
> "So maybe we should try to find a way to take the same path for all
> updates. I'm not too sure how practical this is though."
>
> Damien also said that he doesn't want to still the series on this, but
> since we now have universal plane support for the primary plane I think it
> makes a lot of sense.
> -Daniel
>
>
>> -Daniel
>> "
>>
>>>>
>>>> -Sonika
>>>>
>>>> On 8/7/2014 5:41 PM, Daniel Vetter wrote:
>>>>> On Thu, Aug 07, 2014 at 01:45:31PM +0200, Daniel Vetter wrote:
>>>>>> On Tue, Jul 15, 2014 at 11:11:37AM +0200, Daniel Vetter wrote:
>>>>>>> On Tue, Jul 15, 2014 at 02:10:28PM +0530, sonika.jindal@intel.com wrote:
>>>>>>>> +		/* 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);
>>>>>>>> +				}
>>>>>>>> +			}
>>>>>>>
>>>>>>> Indentation is screwed up here. Also if we convert some of the checks into
>>>>>>> early bails we could de-indent this by one level.
>>>>>>>
>>>>>>> Also Chris mentioned that on some platforms this won't work and it's more
>>>>>>> future-proof to just do a full modeset until we have the proper
>>>>>>> infrastructure.
>>>>>>
>>>>>> Apparently this review here was never addressed, as Chris just pointed out
>>>>>> on irc. I've dropped the patch again.
>>>>>>
>>>>>> I think we need:
>>>>>> - The same sequence as with the sprite set_property function, i.e. we need
>>>>>>    to call the update_plane function (not the raw low-level one, the
>>>>>>    high-level with all the checks).
>>>>>> - The fbc check is wrong and will miss updates when the crtc is off. We
>>>>>>    need to move this into the general list of checks in intel_update_fbc.
>>>>>> - Since this seems to be buggy I want added testcases to combine fbc
>>>>>>    correctness with screen rotation. Probably best to reuse the existing
>>>>>>    fbc testcase and add a bunch or rotated tests.
>>>>>
>>>>> Ok, the check in update_fbc is there, I've been blind. Sorry about all the
>>>>> confusion. So just amounts of calling the higher level function and we can
>>>>> forgo the fbc testing.
>>>>> -Daniel
>>>>>
>>>
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 0/2] 180 Primary plane rotation: calling setplane in set_property
  2014-08-12  3:25                 ` Jindal, Sonika
@ 2014-08-19  6:26                   ` 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  6:26                     ` [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
  0 siblings, 2 replies; 58+ messages in thread
From: sonika.jindal @ 2014-08-19  6:26 UTC (permalink / raw)
  To: intel-gfx

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

As suggested by Daniel, now calling intel_primary_plane_setplane in
set_property.

Inside setplane, the intel_plane's member variables were not updated in the
structure. The first patch does that updation.

>From kms_rotation_crc igt, drmModeSetCrtc was called to set up crtc for primary
plane. So, intel_plane's members like x, y, w, h will not get updated and when
setplane is called from set_property, the values will be invalid in intel_plane
structure. So, updated the kms_plane_crc igt also to call igt_display_commit2
with COMMIT_UNIVERSAL.
For legacy planes, I am still not sure how will this setplane approach work.
Open for suggestions..

Dropping the r-b tag from the second patch.

Sonika Jindal (2):
  drm/i915: Updating intel_plane members for primary plane in setplane
  drm/i915: Add 180 degree primary plane rotation support

 drivers/gpu/drm/i915/i915_reg.h      |    1 +
 drivers/gpu/drm/i915/intel_display.c |  140 +++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_pm.c      |    6 ++
 3 files changed, 143 insertions(+), 4 deletions(-)

-- 
1.7.10.4

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 1/2] drm/i915: Updating plane parameters for primary plane in setplane
  2014-08-19  6:26                   ` [PATCH 0/2] 180 Primary plane rotation: calling setplane in set_property sonika.jindal
@ 2014-08-19  6:26                     ` sonika.jindal
  2014-08-19 20:50                       ` Matt Roper
  2014-08-19  6:26                     ` [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
  1 sibling, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-08-19  6:26 UTC (permalink / raw)
  To: intel-gfx

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

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index e9b578e..1b0e403 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11528,6 +11528,21 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
 		.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
 		.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
 	};
+	const struct {
+		int crtc_x, crtc_y;
+		unsigned int crtc_w, crtc_h;
+		uint32_t src_x, src_y, src_w, src_h;
+	} orig = {
+		.crtc_x = crtc_x,
+		.crtc_y = crtc_y,
+		.crtc_w = crtc_w,
+		.crtc_h = crtc_h,
+		.src_x = src_x,
+		.src_y = src_y,
+		.src_w = src_w,
+		.src_h = src_h,
+	};
+	struct intel_plane *intel_plane = to_intel_plane(plane);
 	bool visible;
 	int ret;
 
@@ -11604,6 +11619,15 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
 
 		return 0;
 	}
+	intel_plane->crtc_x = orig.crtc_x;
+	intel_plane->crtc_y = orig.crtc_y;
+	intel_plane->crtc_w = orig.crtc_w;
+	intel_plane->crtc_h = orig.crtc_h;
+	intel_plane->src_x = orig.src_x;
+	intel_plane->src_y = orig.src_y;
+	intel_plane->src_w = orig.src_w;
+	intel_plane->src_h = orig.src_h;
+	intel_plane->obj = obj;
 
 	ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
 	if (ret)
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  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  6:26                     ` sonika.jindal
  2014-08-19 22:51                       ` Matt Roper
  1 sibling, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-08-19  6:26 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sagar Kamble

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.

v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
set_property(Daniel).

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 |  116 ++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_pm.c      |    6 ++
 3 files changed, 119 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 7a6cc69..f8aaf0b 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4209,6 +4209,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 1b0e403..cc2999b 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2332,6 +2332,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(reg, 0);
@@ -2359,6 +2362,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 			   (intel_crtc->config.pipe_src_w - 1));
 		I915_WRITE(DSPPOS(plane), 0);
 	}
+	dspcntr &= ~DISPPLANE_ROTATE_180;
 
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_C8:
@@ -2398,8 +2402,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) {
@@ -2412,6 +2414,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 		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);
+
+		/* Finding the last pixel of the last line of the display
+		data and adding to linear_offset*/
+		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,
 		      fb->pitches[0]);
@@ -2438,6 +2455,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(reg, 0);
@@ -2453,6 +2473,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
 
+	dspcntr &= ~DISPPLANE_ROTATE_180;
+
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_C8:
 		dspcntr |= DISPPLANE_8BPP;
@@ -2486,14 +2508,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
 		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,
@@ -11647,10 +11681,70 @@ static void intel_plane_destroy(struct drm_plane *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;
+
+		if (crtc == NULL)
+			return -EINVAL;
+
+		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, so disable it when rotation is not 0 and update
+			it when rotation is set back to 0 */
+			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);
+				else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
+					mutex_lock(&dev->struct_mutex);
+					intel_update_fbc(dev);
+					mutex_unlock(&dev->struct_mutex);
+				}
+			}
+
+			intel_primary_plane_setplane(plane, crtc, crtc->primary->fb,
+				intel_plane->crtc_x, intel_plane->crtc_y,
+				intel_plane->crtc_w, intel_plane->crtc_h,
+				intel_plane->src_x, intel_plane->src_y,
+				intel_plane->src_w, intel_plane->src_h);
+
+		} 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,
@@ -11668,6 +11762,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;
 
@@ -11683,6 +11778,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 12f4e14..12f5b99 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -581,6 +581,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

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 1/2] drm/i915: Updating plane parameters for primary plane in setplane
  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
  0 siblings, 1 reply; 58+ messages in thread
From: Matt Roper @ 2014-08-19 20:50 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx

On Tue, Aug 19, 2014 at 11:56:42AM +0530, sonika.jindal@intel.com wrote:
> From: Sonika Jindal <sonika.jindal@intel.com>
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_display.c |   24 ++++++++++++++++++++++++
>  1 file changed, 24 insertions(+)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index e9b578e..1b0e403 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11528,6 +11528,21 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
>  		.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
>  		.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
>  	};
> +	const struct {
> +		int crtc_x, crtc_y;
> +		unsigned int crtc_w, crtc_h;
> +		uint32_t src_x, src_y, src_w, src_h;
> +	} orig = {
> +		.crtc_x = crtc_x,
> +		.crtc_y = crtc_y,
> +		.crtc_w = crtc_w,
> +		.crtc_h = crtc_h,
> +		.src_x = src_x,
> +		.src_y = src_y,
> +		.src_w = src_w,
> +		.src_h = src_h,
> +	};
> +	struct intel_plane *intel_plane = to_intel_plane(plane);
>  	bool visible;
>  	int ret;
>  
> @@ -11604,6 +11619,15 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
>  
>  		return 0;
>  	}
> +	intel_plane->crtc_x = orig.crtc_x;
> +	intel_plane->crtc_y = orig.crtc_y;
> +	intel_plane->crtc_w = orig.crtc_w;
> +	intel_plane->crtc_h = orig.crtc_h;
> +	intel_plane->src_x = orig.src_x;
> +	intel_plane->src_y = orig.src_y;
> +	intel_plane->src_w = orig.src_w;
> +	intel_plane->src_h = orig.src_h;
> +	intel_plane->obj = obj;
>  
>  	ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
>  	if (ret)

I haven't been following all of this thread carefully, but wouldn't you
want to update the intel_plane fields after the point where the function
can no longer fail?  E.g., if I try to setplane() to a new location
while I have a pageflip pending, my request will fail and the plane
position won't update, yet you're still going to be updating the
internal state tracking variables here.  Then if you do an
intel_plane_restore() later you're going to see the plane jump
unexpectedly.

On the other hand, what about the case where the setplane succeeds, but
the plane isn't visible (either because it's fully clipped or because
your crtc isn't active right now).  Those are other paths through the
intel_primary_plane_setplane() function that don't seem to be updating
the intel_plane fields, even though it seems like you'd want to so that
your plane doesn't snap back to an old position on a later
intel_plane_restore().

Sorry if I'm overlooking something obvious here; I haven't been keeping
up with this whole email thread.


Matt

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  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
  0 siblings, 1 reply; 58+ messages in thread
From: Matt Roper @ 2014-08-19 22:51 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx, Sagar Kamble

On Tue, Aug 19, 2014 at 11:56:43AM +0530, sonika.jindal@intel.com wrote:
> 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.
> 
> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
> set_property(Daniel).
> 
> 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 |  116 ++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_pm.c      |    6 ++
>  3 files changed, 119 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 7a6cc69..f8aaf0b 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4209,6 +4209,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 1b0e403..cc2999b 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2332,6 +2332,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  	unsigned long linear_offset;
>  	u32 dspcntr;
>  	u32 reg = DSPCNTR(plane);
> +	int pixel_size;
> +
> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>  
>  	if (!intel_crtc->primary_enabled) {
>  		I915_WRITE(reg, 0);
> @@ -2359,6 +2362,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  			   (intel_crtc->config.pipe_src_w - 1));
>  		I915_WRITE(DSPPOS(plane), 0);
>  	}
> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>  
>  	switch (fb->pixel_format) {
>  	case DRM_FORMAT_C8:
> @@ -2398,8 +2402,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) {
> @@ -2412,6 +2414,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  		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);
> +
> +		/* Finding the last pixel of the last line of the display
> +		data and adding to linear_offset*/
> +		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,
>  		      fb->pitches[0]);
> @@ -2438,6 +2455,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  	unsigned long linear_offset;
>  	u32 dspcntr;
>  	u32 reg = DSPCNTR(plane);
> +	int pixel_size;
> +
> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>  
>  	if (!intel_crtc->primary_enabled) {
>  		I915_WRITE(reg, 0);
> @@ -2453,6 +2473,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
>  
> +	dspcntr &= ~DISPPLANE_ROTATE_180;
> +
>  	switch (fb->pixel_format) {
>  	case DRM_FORMAT_C8:
>  		dspcntr |= DISPPLANE_8BPP;
> @@ -2486,14 +2508,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
>  		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,
> @@ -11647,10 +11681,70 @@ static void intel_plane_destroy(struct drm_plane *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;
> +
> +		if (crtc == NULL)
> +			return -EINVAL;

For sprite planes it looks like we allow this property to be updated
while the plane is off (no FB assigned and thus no crtc pointer) without
error.  Is it intentional that the primary plane behaves differently
here?  Note that you're returning -EINVAL here, but you still leave the
intel_plane->rotation value you set above, which seems a bit odd.

> +
> +		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, so disable it when rotation is not 0 and update
> +			it when rotation is set back to 0 */
> +			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);
> +				else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
> +					mutex_lock(&dev->struct_mutex);
> +					intel_update_fbc(dev);
> +					mutex_unlock(&dev->struct_mutex);
> +				}
> +			}
> +
> +			intel_primary_plane_setplane(plane, crtc, crtc->primary->fb,
> +				intel_plane->crtc_x, intel_plane->crtc_y,
> +				intel_plane->crtc_w, intel_plane->crtc_h,
> +				intel_plane->src_x, intel_plane->src_y,
> +				intel_plane->src_w, intel_plane->src_h);
> +
> +		} else {
> +			DRM_DEBUG_KMS("[CRTC:%d] inactive. Only rotation"
> +				"property is updated\n", crtc->base.id);
> +		}
> +	}
> +	return 0;
> +}

I haven't followed this thread very carefully, so sorry if this has
already been discussed, but could you just use the same set_property()
handler for both primary and sprite planes to avoid duplicate effort?
It seems like you'd only need to make a few changes:

 * Move the wait for asynchronous flips and FBC stuff here into an "if
   (plane type is primary)" block
 * Call intel_plane_restore() here rather than
   intel_primary_plane_setplane()
 * Update intel_plane_restore() such that it calls
   drm_plane->funcs->update_plane() rather than intel_update_plane()
   directly.

I'm sure in the future we'll add other properties that we'll want to
handle on both primary and sprite (and cursor) planes, so having a
single set_property handler might allow us to cut down on needing to
duplicate future code in multiple places.

On the cosmetic side, I also kind of feel like it might make sense to
rename intel_plane_restore() to intel_plane_reprogram() since that seems
like a more accurate description of what we're using the function for
now.


Matt

> +
>  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,
> @@ -11668,6 +11762,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;
>  
> @@ -11683,6 +11778,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 12f4e14..12f5b99 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -581,6 +581,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
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Matt Roper
Graphics Software Engineer
IoTG Platform Enabling & Development
Intel Corporation
(916) 356-2795

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  2014-08-19 22:51                       ` Matt Roper
@ 2014-08-20  5:36                         ` Jindal, Sonika
  2014-08-21  6:15                           ` sonika.jindal
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-20  5:36 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx, Sagar Kamble



On 8/20/2014 4:21 AM, Matt Roper wrote:
> On Tue, Aug 19, 2014 at 11:56:43AM +0530, sonika.jindal@intel.com wrote:
>> 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.
>>
>> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
>> set_property(Daniel).
>>
>> 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 |  116 ++++++++++++++++++++++++++++++++--
>>   drivers/gpu/drm/i915/intel_pm.c      |    6 ++
>>   3 files changed, 119 insertions(+), 4 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index 7a6cc69..f8aaf0b 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -4209,6 +4209,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 1b0e403..cc2999b 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -2332,6 +2332,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>   	unsigned long linear_offset;
>>   	u32 dspcntr;
>>   	u32 reg = DSPCNTR(plane);
>> +	int pixel_size;
>> +
>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>>
>>   	if (!intel_crtc->primary_enabled) {
>>   		I915_WRITE(reg, 0);
>> @@ -2359,6 +2362,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>   			   (intel_crtc->config.pipe_src_w - 1));
>>   		I915_WRITE(DSPPOS(plane), 0);
>>   	}
>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>>
>>   	switch (fb->pixel_format) {
>>   	case DRM_FORMAT_C8:
>> @@ -2398,8 +2402,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) {
>> @@ -2412,6 +2414,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>   		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);
>> +
>> +		/* Finding the last pixel of the last line of the display
>> +		data and adding to linear_offset*/
>> +		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,
>>   		      fb->pitches[0]);
>> @@ -2438,6 +2455,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>   	unsigned long linear_offset;
>>   	u32 dspcntr;
>>   	u32 reg = DSPCNTR(plane);
>> +	int pixel_size;
>> +
>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>>
>>   	if (!intel_crtc->primary_enabled) {
>>   		I915_WRITE(reg, 0);
>> @@ -2453,6 +2473,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>   	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>>   		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
>>
>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>> +
>>   	switch (fb->pixel_format) {
>>   	case DRM_FORMAT_C8:
>>   		dspcntr |= DISPPLANE_8BPP;
>> @@ -2486,14 +2508,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>   	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
>>   		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,
>> @@ -11647,10 +11681,70 @@ static void intel_plane_destroy(struct drm_plane *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;
>> +
>> +		if (crtc == NULL)
>> +			return -EINVAL;
>
> For sprite planes it looks like we allow this property to be updated
> while the plane is off (no FB assigned and thus no crtc pointer) without
> error.  Is it intentional that the primary plane behaves differently
> here?  Note that you're returning -EINVAL here, but you still leave the
> intel_plane->rotation value you set above, which seems a bit odd.
>
I think it is ok to leave the rotation updated because in the next 
update it will be reflected. The check is to avoid calling of setplane 
if the crtc is inactive.

>> +
>> +		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, so disable it when rotation is not 0 and update
>> +			it when rotation is set back to 0 */
>> +			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);
>> +				else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
>> +					mutex_lock(&dev->struct_mutex);
>> +					intel_update_fbc(dev);
>> +					mutex_unlock(&dev->struct_mutex);
>> +				}
>> +			}
>> +
>> +			intel_primary_plane_setplane(plane, crtc, crtc->primary->fb,
>> +				intel_plane->crtc_x, intel_plane->crtc_y,
>> +				intel_plane->crtc_w, intel_plane->crtc_h,
>> +				intel_plane->src_x, intel_plane->src_y,
>> +				intel_plane->src_w, intel_plane->src_h);
>> +
>> +		} else {
>> +			DRM_DEBUG_KMS("[CRTC:%d] inactive. Only rotation"
>> +				"property is updated\n", crtc->base.id);
>> +		}
>> +	}
>> +	return 0;
>> +}
>
> I haven't followed this thread very carefully, so sorry if this has
> already been discussed, but could you just use the same set_property()
> handler for both primary and sprite planes to avoid duplicate effort?
> It seems like you'd only need to make a few changes:
>
>   * Move the wait for asynchronous flips and FBC stuff here into an "if
>     (plane type is primary)" block
>   * Call intel_plane_restore() here rather than
>     intel_primary_plane_setplane()
>   * Update intel_plane_restore() such that it calls
>     drm_plane->funcs->update_plane() rather than intel_update_plane()
>     directly.
>
> I'm sure in the future we'll add other properties that we'll want to
> handle on both primary and sprite (and cursor) planes, so having a
> single set_property handler might allow us to cut down on needing to
> duplicate future code in multiple places.
>
Hmm, yes having single set_property function might be right approach.
Since, it all started with crtc property and not a separate primary 
plane property they are maintained separately.

> On the cosmetic side, I also kind of feel like it might make sense to
> rename intel_plane_restore() to intel_plane_reprogram() since that seems
> like a more accurate description of what we're using the function for
> now.
>
>
> Matt
>
>> +
>>   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,
>> @@ -11668,6 +11762,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;
>>
>> @@ -11683,6 +11778,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 12f4e14..12f5b99 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -581,6 +581,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
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 1/2] drm/i915: Updating plane parameters for primary plane in setplane
  2014-08-19 20:50                       ` Matt Roper
@ 2014-08-20  5:53                         ` Jindal, Sonika
  2014-08-21  6:14                           ` sonika.jindal
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-20  5:53 UTC (permalink / raw)
  To: Matt Roper; +Cc: intel-gfx



On 8/20/2014 2:20 AM, Matt Roper wrote:
> On Tue, Aug 19, 2014 at 11:56:42AM +0530, sonika.jindal@intel.com wrote:
>> From: Sonika Jindal <sonika.jindal@intel.com>
>>
>> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
>> ---
>>   drivers/gpu/drm/i915/intel_display.c |   24 ++++++++++++++++++++++++
>>   1 file changed, 24 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
>> index e9b578e..1b0e403 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -11528,6 +11528,21 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
>>   		.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
>>   		.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
>>   	};
>> +	const struct {
>> +		int crtc_x, crtc_y;
>> +		unsigned int crtc_w, crtc_h;
>> +		uint32_t src_x, src_y, src_w, src_h;
>> +	} orig = {
>> +		.crtc_x = crtc_x,
>> +		.crtc_y = crtc_y,
>> +		.crtc_w = crtc_w,
>> +		.crtc_h = crtc_h,
>> +		.src_x = src_x,
>> +		.src_y = src_y,
>> +		.src_w = src_w,
>> +		.src_h = src_h,
>> +	};
>> +	struct intel_plane *intel_plane = to_intel_plane(plane);
>>   	bool visible;
>>   	int ret;
>>
>> @@ -11604,6 +11619,15 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
>>
>>   		return 0;
>>   	}
>> +	intel_plane->crtc_x = orig.crtc_x;
>> +	intel_plane->crtc_y = orig.crtc_y;
>> +	intel_plane->crtc_w = orig.crtc_w;
>> +	intel_plane->crtc_h = orig.crtc_h;
>> +	intel_plane->src_x = orig.src_x;
>> +	intel_plane->src_y = orig.src_y;
>> +	intel_plane->src_w = orig.src_w;
>> +	intel_plane->src_h = orig.src_h;
>> +	intel_plane->obj = obj;
>>
>>   	ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
>>   	if (ret)
>
> I haven't been following all of this thread carefully, but wouldn't you
> want to update the intel_plane fields after the point where the function
> can no longer fail?  E.g., if I try to setplane() to a new location
> while I have a pageflip pending, my request will fail and the plane
> position won't update, yet you're still going to be updating the
> internal state tracking variables here.  Then if you do an
> intel_plane_restore() later you're going to see the plane jump
> unexpectedly.
>
> On the other hand, what about the case where the setplane succeeds, but
> the plane isn't visible (either because it's fully clipped or because
> your crtc isn't active right now).  Those are other paths through the
> intel_primary_plane_setplane() function that don't seem to be updating
> the intel_plane fields, even though it seems like you'd want to so that
> your plane doesn't snap back to an old position on a later
> intel_plane_restore().
>
I understand your points, but I am not sure why the updation of these 
intel_plane member variables was left in the first place. Do you a 
reason why this was not present till now? Am I missing something?

> Sorry if I'm overlooking something obvious here; I haven't been keeping
> up with this whole email thread.
>
>
> Matt
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH 1/2] drm/i915: Updating plane parameters for primary plane in setplane
  2014-08-20  5:53                         ` Jindal, Sonika
@ 2014-08-21  6:14                           ` sonika.jindal
  2014-08-25 20:42                             ` Daniel Vetter
  0 siblings, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-08-21  6:14 UTC (permalink / raw)
  To: intel-gfx

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

v2: Moving setting of plane members in the end to take care of failure cases and
not-visible cases (Matt).

Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>
---
 drivers/gpu/drm/i915/intel_display.c |   38 +++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 0b327eb..f2a8797 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -11594,6 +11594,21 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
 		.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
 		.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
 	};
+	const struct {
+		int crtc_x, crtc_y;
+		unsigned int crtc_w, crtc_h;
+		uint32_t src_x, src_y, src_w, src_h;
+	} orig = {
+		.crtc_x = crtc_x,
+		.crtc_y = crtc_y,
+		.crtc_w = crtc_w,
+		.crtc_h = crtc_h,
+		.src_x = src_x,
+		.src_y = src_y,
+		.src_w = src_w,
+		.src_h = src_h,
+	};
+	struct intel_plane *intel_plane = to_intel_plane(plane);
 	bool visible;
 	int ret;
 
@@ -11668,15 +11683,24 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
 
 		mutex_unlock(&dev->struct_mutex);
 
-		return 0;
-	}
+	} else {
+		ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
+		if (ret)
+			return ret;
 
-	ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
-	if (ret)
-		return ret;
+		if (!intel_crtc->primary_enabled)
+			intel_enable_primary_hw_plane(plane, crtc);
+	}
 
-	if (!intel_crtc->primary_enabled)
-		intel_enable_primary_hw_plane(plane, crtc);
+	intel_plane->crtc_x = orig.crtc_x;
+	intel_plane->crtc_y = orig.crtc_y;
+	intel_plane->crtc_w = orig.crtc_w;
+	intel_plane->crtc_h = orig.crtc_h;
+	intel_plane->src_x = orig.src_x;
+	intel_plane->src_y = orig.src_y;
+	intel_plane->src_w = orig.src_w;
+	intel_plane->src_h = orig.src_h;
+	intel_plane->obj = obj;
 
 	return 0;
 }
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  2014-08-20  5:36                         ` Jindal, Sonika
@ 2014-08-21  6:15                           ` sonika.jindal
  2014-08-21  8:33                             ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-08-21  6:15 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sagar Kamble

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.

v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
set_property(Daniel).

v11: Using same set_property function for both primary and sprite, Adding
primary plane specific code in the same function (Matt).

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 |   57 +++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_drv.h     |    3 ++
 drivers/gpu/drm/i915/intel_pm.c      |    6 ++++
 drivers/gpu/drm/i915/intel_sprite.c  |   33 ++++++++++++++++++--
 5 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 203062e..142ac52 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4214,6 +4214,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 f2a8797..22851a9 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(reg, 0);
@@ -2411,6 +2414,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 			   (intel_crtc->config.pipe_src_w - 1));
 		I915_WRITE(DSPPOS(plane), 0);
 	}
+	dspcntr &= ~DISPPLANE_ROTATE_180;
 
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_C8:
@@ -2450,8 +2454,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) {
@@ -2464,6 +2466,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 		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);
+
+		/* Finding the last pixel of the last line of the display
+		data and adding to linear_offset*/
+		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,
 		      fb->pitches[0]);
@@ -2490,6 +2507,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(reg, 0);
@@ -2505,6 +2525,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
 		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
 
+	dspcntr &= ~DISPPLANE_ROTATE_180;
+
 	switch (fb->pixel_format) {
 	case DRM_FORMAT_C8:
 		dspcntr |= DISPPLANE_8BPP;
@@ -2538,14 +2560,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
 		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,
@@ -11717,6 +11751,7 @@ 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_plane_set_property
 };
 
 static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
@@ -11734,6 +11769,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;
 
@@ -11749,6 +11785,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d683a20..3e5d6b3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
 int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
 void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
 			       enum plane plane);
+int intel_plane_set_property(struct drm_plane *plane,
+				    struct drm_property *prop,
+				    uint64_t val);
 int intel_plane_restore(struct drm_plane *plane);
 void intel_plane_disable(struct drm_plane *plane);
 int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c8f744c..1ab3e11 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -581,6 +581,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())
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0bdb00b..ad09ba1 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1218,12 +1218,15 @@ out_unlock:
 	return ret;
 }
 
-static int intel_plane_set_property(struct drm_plane *plane,
+int intel_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;
 	int ret = -ENOENT;
 
@@ -1232,6 +1235,32 @@ static int intel_plane_set_property(struct drm_plane *plane,
 		if (hweight32(val & 0xf) != 1)
 			return -EINVAL;
 
+		if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
+			if (crtc == NULL)
+				return -EINVAL;
+
+			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, so disable it when rotation is not 0 and update
+				   it when rotation is set back to 0 */
+				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);
+					else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
+						mutex_lock(&dev->struct_mutex);
+						intel_update_fbc(dev);
+						mutex_unlock(&dev->struct_mutex);
+					}
+				}
+			}
+		}
+
 		old_val = intel_plane->rotation;
 		intel_plane->rotation = val;
 		ret = intel_plane_restore(plane);
@@ -1249,7 +1278,7 @@ int intel_plane_restore(struct drm_plane *plane)
 	if (!plane->crtc || !plane->fb)
 		return 0;
 
-	return intel_update_plane(plane, plane->crtc, plane->fb,
+	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
 				  intel_plane->crtc_x, intel_plane->crtc_y,
 				  intel_plane->crtc_w, intel_plane->crtc_h,
 				  intel_plane->src_x, intel_plane->src_y,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  2014-08-21  6:15                           ` sonika.jindal
@ 2014-08-21  8:33                             ` Ville Syrjälä
  2014-08-21 11:44                               ` Jindal, Sonika
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2014-08-21  8:33 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx, Sagar Kamble

On Thu, Aug 21, 2014 at 11:45:41AM +0530, sonika.jindal@intel.com wrote:
> 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.
> 
> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
> set_property(Daniel).
> 
> v11: Using same set_property function for both primary and sprite, Adding
> primary plane specific code in the same function (Matt).
> 
> 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 |   57 +++++++++++++++++++++++++++++++---
>  drivers/gpu/drm/i915/intel_drv.h     |    3 ++
>  drivers/gpu/drm/i915/intel_pm.c      |    6 ++++
>  drivers/gpu/drm/i915/intel_sprite.c  |   33 ++++++++++++++++++--
>  5 files changed, 94 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 203062e..142ac52 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4214,6 +4214,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 f2a8797..22851a9 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  	unsigned long linear_offset;
>  	u32 dspcntr;
>  	u32 reg = DSPCNTR(plane);
> +	int pixel_size;
> +
> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>  
>  	if (!intel_crtc->primary_enabled) {
>  		I915_WRITE(reg, 0);
> @@ -2411,6 +2414,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  			   (intel_crtc->config.pipe_src_w - 1));
>  		I915_WRITE(DSPPOS(plane), 0);
>  	}
> +	dspcntr &= ~DISPPLANE_ROTATE_180;

No longer needed. We start building DSPCNTR from scratch.

>  
>  	switch (fb->pixel_format) {
>  	case DRM_FORMAT_C8:
> @@ -2450,8 +2454,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) {
> @@ -2464,6 +2466,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  		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);
> +
> +		/* Finding the last pixel of the last line of the display
> +		data and adding to linear_offset*/
> +		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,
>  		      fb->pitches[0]);
> @@ -2490,6 +2507,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  	unsigned long linear_offset;
>  	u32 dspcntr;
>  	u32 reg = DSPCNTR(plane);
> +	int pixel_size;
> +
> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>  
>  	if (!intel_crtc->primary_enabled) {
>  		I915_WRITE(reg, 0);
> @@ -2505,6 +2525,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>  		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
>  
> +	dspcntr &= ~DISPPLANE_ROTATE_180;
> +

ditto

>  	switch (fb->pixel_format) {
>  	case DRM_FORMAT_C8:
>  		dspcntr |= DISPPLANE_8BPP;
> @@ -2538,14 +2560,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
>  		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;

Formatting looks rather wonky. In this case I think we need to
accept that we can't make it fit into 80 columns neatly and just
use longer lines.

I would just make it:
linear_offset +=
	(intel_crtc->config.pipe_src_h - 1) * fb->pitches[0] +
	(intel_crtc->config.pipe_src_w - 1) * pixel_size;

so that we have the x vs. y offsets neatly on their own lines. Same for
the other instance of this code. Or if you prefer you could to refactor
that bit of code into a small helper function.

> +		}
> +	}
> +
> +	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,
> @@ -11717,6 +11751,7 @@ 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_plane_set_property
>  };
>  
>  static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
> @@ -11734,6 +11769,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;
>  
> @@ -11749,6 +11785,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index d683a20..3e5d6b3 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
>  int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
>  void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
>  			       enum plane plane);
> +int intel_plane_set_property(struct drm_plane *plane,
> +				    struct drm_property *prop,
> +				    uint64_t val);
>  int intel_plane_restore(struct drm_plane *plane);
>  void intel_plane_disable(struct drm_plane *plane);
>  int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index c8f744c..1ab3e11 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -581,6 +581,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())
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 0bdb00b..ad09ba1 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1218,12 +1218,15 @@ out_unlock:
>  	return ret;
>  }
>  
> -static int intel_plane_set_property(struct drm_plane *plane,
> +int intel_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;
>  	int ret = -ENOENT;
>  
> @@ -1232,6 +1235,32 @@ static int intel_plane_set_property(struct drm_plane *plane,
>  		if (hweight32(val & 0xf) != 1)
>  			return -EINVAL;
>  
> +		if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
> +			if (crtc == NULL)
> +				return -EINVAL;
> +
> +			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, so disable it when rotation is not 0 and update
> +				   it when rotation is set back to 0 */
> +				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);
> +					else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
> +						mutex_lock(&dev->struct_mutex);
> +						intel_update_fbc(dev);
> +						mutex_unlock(&dev->struct_mutex);
> +					}
> +				}
> +			}
> +		}

I think Daniel wanted to shovel all of this into
intel_primary_plane_setplane().

In fact the intel_update_fbc() is already there in
intel_pipe_set_base(), although I think should get moved out so that it
can be placed on the correct side of intel_enable_primary_hw_plane().
But that can be done as a followup later. And we also lack the
disable_fbc call from intel_primary_plane_disable().

> +
>  		old_val = intel_plane->rotation;
>  		intel_plane->rotation = val;
>  		ret = intel_plane_restore(plane);
> @@ -1249,7 +1278,7 @@ int intel_plane_restore(struct drm_plane *plane)
>  	if (!plane->crtc || !plane->fb)
>  		return 0;
>  
> -	return intel_update_plane(plane, plane->crtc, plane->fb,
> +	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
>  				  intel_plane->crtc_x, intel_plane->crtc_y,
>  				  intel_plane->crtc_w, intel_plane->crtc_h,
>  				  intel_plane->src_x, intel_plane->src_y,
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  2014-08-21  8:33                             ` Ville Syrjälä
@ 2014-08-21 11:44                               ` Jindal, Sonika
  2014-08-21 13:37                                 ` Ville Syrjälä
  0 siblings, 1 reply; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-21 11:44 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Sagar Kamble



On 8/21/2014 2:03 PM, Ville Syrjälä wrote:
> On Thu, Aug 21, 2014 at 11:45:41AM +0530, sonika.jindal@intel.com wrote:
>> 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.
>>
>> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
>> set_property(Daniel).
>>
>> v11: Using same set_property function for both primary and sprite, Adding
>> primary plane specific code in the same function (Matt).
>>
>> 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 |   57 +++++++++++++++++++++++++++++++---
>>   drivers/gpu/drm/i915/intel_drv.h     |    3 ++
>>   drivers/gpu/drm/i915/intel_pm.c      |    6 ++++
>>   drivers/gpu/drm/i915/intel_sprite.c  |   33 ++++++++++++++++++--
>>   5 files changed, 94 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>> index 203062e..142ac52 100644
>> --- a/drivers/gpu/drm/i915/i915_reg.h
>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>> @@ -4214,6 +4214,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 f2a8797..22851a9 100644
>> --- a/drivers/gpu/drm/i915/intel_display.c
>> +++ b/drivers/gpu/drm/i915/intel_display.c
>> @@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>   	unsigned long linear_offset;
>>   	u32 dspcntr;
>>   	u32 reg = DSPCNTR(plane);
>> +	int pixel_size;
>> +
>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>>
>>   	if (!intel_crtc->primary_enabled) {
>>   		I915_WRITE(reg, 0);
>> @@ -2411,6 +2414,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>   			   (intel_crtc->config.pipe_src_w - 1));
>>   		I915_WRITE(DSPPOS(plane), 0);
>>   	}
>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>
> No longer needed. We start building DSPCNTR from scratch.
>
>>
>>   	switch (fb->pixel_format) {
>>   	case DRM_FORMAT_C8:
>> @@ -2450,8 +2454,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) {
>> @@ -2464,6 +2466,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>   		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);
>> +
>> +		/* Finding the last pixel of the last line of the display
>> +		data and adding to linear_offset*/
>> +		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,
>>   		      fb->pitches[0]);
>> @@ -2490,6 +2507,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>   	unsigned long linear_offset;
>>   	u32 dspcntr;
>>   	u32 reg = DSPCNTR(plane);
>> +	int pixel_size;
>> +
>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>>
>>   	if (!intel_crtc->primary_enabled) {
>>   		I915_WRITE(reg, 0);
>> @@ -2505,6 +2525,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>   	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>>   		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
>>
>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>> +
>
> ditto
>
>>   	switch (fb->pixel_format) {
>>   	case DRM_FORMAT_C8:
>>   		dspcntr |= DISPPLANE_8BPP;
>> @@ -2538,14 +2560,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>   	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
>>   		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;
>
> Formatting looks rather wonky. In this case I think we need to
> accept that we can't make it fit into 80 columns neatly and just
> use longer lines.
>
> I would just make it:
> linear_offset +=
> 	(intel_crtc->config.pipe_src_h - 1) * fb->pitches[0] +
> 	(intel_crtc->config.pipe_src_w - 1) * pixel_size;
>
> so that we have the x vs. y offsets neatly on their own lines. Same for
> the other instance of this code. Or if you prefer you could to refactor
> that bit of code into a small helper function.
>
>> +		}
>> +	}
>> +
>> +	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,
>> @@ -11717,6 +11751,7 @@ 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_plane_set_property
>>   };
>>
>>   static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>> @@ -11734,6 +11769,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;
>>
>> @@ -11749,6 +11785,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>> index d683a20..3e5d6b3 100644
>> --- a/drivers/gpu/drm/i915/intel_drv.h
>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>> @@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
>>   int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
>>   void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
>>   			       enum plane plane);
>> +int intel_plane_set_property(struct drm_plane *plane,
>> +				    struct drm_property *prop,
>> +				    uint64_t val);
>>   int intel_plane_restore(struct drm_plane *plane);
>>   void intel_plane_disable(struct drm_plane *plane);
>>   int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>> index c8f744c..1ab3e11 100644
>> --- a/drivers/gpu/drm/i915/intel_pm.c
>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>> @@ -581,6 +581,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())
>> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
>> index 0bdb00b..ad09ba1 100644
>> --- a/drivers/gpu/drm/i915/intel_sprite.c
>> +++ b/drivers/gpu/drm/i915/intel_sprite.c
>> @@ -1218,12 +1218,15 @@ out_unlock:
>>   	return ret;
>>   }
>>
>> -static int intel_plane_set_property(struct drm_plane *plane,
>> +int intel_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;
>>   	int ret = -ENOENT;
>>
>> @@ -1232,6 +1235,32 @@ static int intel_plane_set_property(struct drm_plane *plane,
>>   		if (hweight32(val & 0xf) != 1)
>>   			return -EINVAL;
>>
>> +		if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
>> +			if (crtc == NULL)
>> +				return -EINVAL;
>> +
>> +			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, so disable it when rotation is not 0 and update
>> +				   it when rotation is set back to 0 */
>> +				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);
>> +					else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
>> +						mutex_lock(&dev->struct_mutex);
>> +						intel_update_fbc(dev);
>> +						mutex_unlock(&dev->struct_mutex);
>> +					}
>> +				}
>> +			}
>> +		}
>
> I think Daniel wanted to shovel all of this into
> intel_primary_plane_setplane().
>
I am not sure about that, Matt suggested this change and here we do 
disable fbc for rotated plane. So, it makes more sense to keep it in 
set_property.
What do you suggest?
> In fact the intel_update_fbc() is already there in
> intel_pipe_set_base(), although I think should get moved out so that it
> can be placed on the correct side of intel_enable_primary_hw_plane().
> But that can be done as a followup later. And we also lack the
> disable_fbc call from intel_primary_plane_disable().
>
>> +
>>   		old_val = intel_plane->rotation;
>>   		intel_plane->rotation = val;
>>   		ret = intel_plane_restore(plane);
>> @@ -1249,7 +1278,7 @@ int intel_plane_restore(struct drm_plane *plane)
>>   	if (!plane->crtc || !plane->fb)
>>   		return 0;
>>
>> -	return intel_update_plane(plane, plane->crtc, plane->fb,
>> +	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
>>   				  intel_plane->crtc_x, intel_plane->crtc_y,
>>   				  intel_plane->crtc_w, intel_plane->crtc_h,
>>   				  intel_plane->src_x, intel_plane->src_y,
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> Intel-gfx mailing list
>> Intel-gfx@lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  2014-08-21 11:44                               ` Jindal, Sonika
@ 2014-08-21 13:37                                 ` Ville Syrjälä
  2014-08-22  3:59                                   ` Jindal, Sonika
  0 siblings, 1 reply; 58+ messages in thread
From: Ville Syrjälä @ 2014-08-21 13:37 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx, Sagar Kamble

On Thu, Aug 21, 2014 at 05:14:35PM +0530, Jindal, Sonika wrote:
> 
> 
> On 8/21/2014 2:03 PM, Ville Syrjälä wrote:
> > On Thu, Aug 21, 2014 at 11:45:41AM +0530, sonika.jindal@intel.com wrote:
> >> 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.
> >>
> >> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
> >> set_property(Daniel).
> >>
> >> v11: Using same set_property function for both primary and sprite, Adding
> >> primary plane specific code in the same function (Matt).
> >>
> >> 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 |   57 +++++++++++++++++++++++++++++++---
> >>   drivers/gpu/drm/i915/intel_drv.h     |    3 ++
> >>   drivers/gpu/drm/i915/intel_pm.c      |    6 ++++
> >>   drivers/gpu/drm/i915/intel_sprite.c  |   33 ++++++++++++++++++--
> >>   5 files changed, 94 insertions(+), 6 deletions(-)
> >>
> >> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> >> index 203062e..142ac52 100644
> >> --- a/drivers/gpu/drm/i915/i915_reg.h
> >> +++ b/drivers/gpu/drm/i915/i915_reg.h
> >> @@ -4214,6 +4214,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 f2a8797..22851a9 100644
> >> --- a/drivers/gpu/drm/i915/intel_display.c
> >> +++ b/drivers/gpu/drm/i915/intel_display.c
> >> @@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>   	unsigned long linear_offset;
> >>   	u32 dspcntr;
> >>   	u32 reg = DSPCNTR(plane);
> >> +	int pixel_size;
> >> +
> >> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> >>
> >>   	if (!intel_crtc->primary_enabled) {
> >>   		I915_WRITE(reg, 0);
> >> @@ -2411,6 +2414,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>   			   (intel_crtc->config.pipe_src_w - 1));
> >>   		I915_WRITE(DSPPOS(plane), 0);
> >>   	}
> >> +	dspcntr &= ~DISPPLANE_ROTATE_180;
> >
> > No longer needed. We start building DSPCNTR from scratch.
> >
> >>
> >>   	switch (fb->pixel_format) {
> >>   	case DRM_FORMAT_C8:
> >> @@ -2450,8 +2454,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) {
> >> @@ -2464,6 +2466,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>   		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);
> >> +
> >> +		/* Finding the last pixel of the last line of the display
> >> +		data and adding to linear_offset*/
> >> +		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,
> >>   		      fb->pitches[0]);
> >> @@ -2490,6 +2507,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
> >>   	unsigned long linear_offset;
> >>   	u32 dspcntr;
> >>   	u32 reg = DSPCNTR(plane);
> >> +	int pixel_size;
> >> +
> >> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> >>
> >>   	if (!intel_crtc->primary_enabled) {
> >>   		I915_WRITE(reg, 0);
> >> @@ -2505,6 +2525,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
> >>   	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> >>   		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
> >>
> >> +	dspcntr &= ~DISPPLANE_ROTATE_180;
> >> +
> >
> > ditto
> >
> >>   	switch (fb->pixel_format) {
> >>   	case DRM_FORMAT_C8:
> >>   		dspcntr |= DISPPLANE_8BPP;
> >> @@ -2538,14 +2560,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
> >>   	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
> >>   		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;
> >
> > Formatting looks rather wonky. In this case I think we need to
> > accept that we can't make it fit into 80 columns neatly and just
> > use longer lines.
> >
> > I would just make it:
> > linear_offset +=
> > 	(intel_crtc->config.pipe_src_h - 1) * fb->pitches[0] +
> > 	(intel_crtc->config.pipe_src_w - 1) * pixel_size;
> >
> > so that we have the x vs. y offsets neatly on their own lines. Same for
> > the other instance of this code. Or if you prefer you could to refactor
> > that bit of code into a small helper function.
> >
> >> +		}
> >> +	}
> >> +
> >> +	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,
> >> @@ -11717,6 +11751,7 @@ 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_plane_set_property
> >>   };
> >>
> >>   static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
> >> @@ -11734,6 +11769,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;
> >>
> >> @@ -11749,6 +11785,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> >> index d683a20..3e5d6b3 100644
> >> --- a/drivers/gpu/drm/i915/intel_drv.h
> >> +++ b/drivers/gpu/drm/i915/intel_drv.h
> >> @@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
> >>   int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
> >>   void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
> >>   			       enum plane plane);
> >> +int intel_plane_set_property(struct drm_plane *plane,
> >> +				    struct drm_property *prop,
> >> +				    uint64_t val);
> >>   int intel_plane_restore(struct drm_plane *plane);
> >>   void intel_plane_disable(struct drm_plane *plane);
> >>   int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
> >> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> >> index c8f744c..1ab3e11 100644
> >> --- a/drivers/gpu/drm/i915/intel_pm.c
> >> +++ b/drivers/gpu/drm/i915/intel_pm.c
> >> @@ -581,6 +581,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())
> >> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> >> index 0bdb00b..ad09ba1 100644
> >> --- a/drivers/gpu/drm/i915/intel_sprite.c
> >> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> >> @@ -1218,12 +1218,15 @@ out_unlock:
> >>   	return ret;
> >>   }
> >>
> >> -static int intel_plane_set_property(struct drm_plane *plane,
> >> +int intel_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;
> >>   	int ret = -ENOENT;
> >>
> >> @@ -1232,6 +1235,32 @@ static int intel_plane_set_property(struct drm_plane *plane,
> >>   		if (hweight32(val & 0xf) != 1)
> >>   			return -EINVAL;
> >>
> >> +		if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
> >> +			if (crtc == NULL)
> >> +				return -EINVAL;
> >> +
> >> +			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, so disable it when rotation is not 0 and update
> >> +				   it when rotation is set back to 0 */
> >> +				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);
> >> +					else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
> >> +						mutex_lock(&dev->struct_mutex);
> >> +						intel_update_fbc(dev);
> >> +						mutex_unlock(&dev->struct_mutex);
> >> +					}
> >> +				}
> >> +			}
> >> +		}
> >
> > I think Daniel wanted to shovel all of this into
> > intel_primary_plane_setplane().
> >
> I am not sure about that, Matt suggested this change and here we do 
> disable fbc for rotated plane. So, it makes more sense to keep it in 
> set_property.
> What do you suggest?

We anyway may have to disable fbc in setplace due to other factors
(pixel format etc.) so having all the logic in the same place makes
sense.

> > In fact the intel_update_fbc() is already there in
> > intel_pipe_set_base(), although I think should get moved out so that it
> > can be placed on the correct side of intel_enable_primary_hw_plane().
> > But that can be done as a followup later. And we also lack the
> > disable_fbc call from intel_primary_plane_disable().
> >
> >> +
> >>   		old_val = intel_plane->rotation;
> >>   		intel_plane->rotation = val;
> >>   		ret = intel_plane_restore(plane);
> >> @@ -1249,7 +1278,7 @@ int intel_plane_restore(struct drm_plane *plane)
> >>   	if (!plane->crtc || !plane->fb)
> >>   		return 0;
> >>
> >> -	return intel_update_plane(plane, plane->crtc, plane->fb,
> >> +	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
> >>   				  intel_plane->crtc_x, intel_plane->crtc_y,
> >>   				  intel_plane->crtc_w, intel_plane->crtc_h,
> >>   				  intel_plane->src_x, intel_plane->src_y,
> >> --
> >> 1.7.10.4
> >>
> >> _______________________________________________
> >> Intel-gfx mailing list
> >> Intel-gfx@lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  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ä
  0 siblings, 2 replies; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-22  3:59 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Sagar Kamble



On 8/21/2014 7:07 PM, Ville Syrjälä wrote:
> On Thu, Aug 21, 2014 at 05:14:35PM +0530, Jindal, Sonika wrote:
>>
>>
>> On 8/21/2014 2:03 PM, Ville Syrjälä wrote:
>>> On Thu, Aug 21, 2014 at 11:45:41AM +0530, sonika.jindal@intel.com wrote:
>>>> 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.
>>>>
>>>> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
>>>> set_property(Daniel).
>>>>
>>>> v11: Using same set_property function for both primary and sprite, Adding
>>>> primary plane specific code in the same function (Matt).
>>>>
>>>> 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 |   57 +++++++++++++++++++++++++++++++---
>>>>    drivers/gpu/drm/i915/intel_drv.h     |    3 ++
>>>>    drivers/gpu/drm/i915/intel_pm.c      |    6 ++++
>>>>    drivers/gpu/drm/i915/intel_sprite.c  |   33 ++++++++++++++++++--
>>>>    5 files changed, 94 insertions(+), 6 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>>>> index 203062e..142ac52 100644
>>>> --- a/drivers/gpu/drm/i915/i915_reg.h
>>>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>>>> @@ -4214,6 +4214,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 f2a8797..22851a9 100644
>>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>>> @@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>>>    	unsigned long linear_offset;
>>>>    	u32 dspcntr;
>>>>    	u32 reg = DSPCNTR(plane);
>>>> +	int pixel_size;
>>>> +
>>>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>>>>
>>>>    	if (!intel_crtc->primary_enabled) {
>>>>    		I915_WRITE(reg, 0);
>>>> @@ -2411,6 +2414,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>>>    			   (intel_crtc->config.pipe_src_w - 1));
>>>>    		I915_WRITE(DSPPOS(plane), 0);
>>>>    	}
>>>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>>>
>>> No longer needed. We start building DSPCNTR from scratch.
>>>
>>>>
>>>>    	switch (fb->pixel_format) {
>>>>    	case DRM_FORMAT_C8:
>>>> @@ -2450,8 +2454,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) {
>>>> @@ -2464,6 +2466,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>>>    		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);
>>>> +
>>>> +		/* Finding the last pixel of the last line of the display
>>>> +		data and adding to linear_offset*/
>>>> +		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,
>>>>    		      fb->pitches[0]);
>>>> @@ -2490,6 +2507,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>>>    	unsigned long linear_offset;
>>>>    	u32 dspcntr;
>>>>    	u32 reg = DSPCNTR(plane);
>>>> +	int pixel_size;
>>>> +
>>>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>>>>
>>>>    	if (!intel_crtc->primary_enabled) {
>>>>    		I915_WRITE(reg, 0);
>>>> @@ -2505,6 +2525,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>>>    	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>>>>    		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
>>>>
>>>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>>>> +
>>>
>>> ditto
>>>
>>>>    	switch (fb->pixel_format) {
>>>>    	case DRM_FORMAT_C8:
>>>>    		dspcntr |= DISPPLANE_8BPP;
>>>> @@ -2538,14 +2560,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>>>    	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
>>>>    		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;
>>>
>>> Formatting looks rather wonky. In this case I think we need to
>>> accept that we can't make it fit into 80 columns neatly and just
>>> use longer lines.
>>>
>>> I would just make it:
>>> linear_offset +=
>>> 	(intel_crtc->config.pipe_src_h - 1) * fb->pitches[0] +
>>> 	(intel_crtc->config.pipe_src_w - 1) * pixel_size;
>>>
>>> so that we have the x vs. y offsets neatly on their own lines. Same for
>>> the other instance of this code. Or if you prefer you could to refactor
>>> that bit of code into a small helper function.
>>>
>>>> +		}
>>>> +	}
>>>> +
>>>> +	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,
>>>> @@ -11717,6 +11751,7 @@ 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_plane_set_property
>>>>    };
>>>>
>>>>    static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>>>> @@ -11734,6 +11769,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;
>>>>
>>>> @@ -11749,6 +11785,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>>>> index d683a20..3e5d6b3 100644
>>>> --- a/drivers/gpu/drm/i915/intel_drv.h
>>>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>>>> @@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
>>>>    int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
>>>>    void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
>>>>    			       enum plane plane);
>>>> +int intel_plane_set_property(struct drm_plane *plane,
>>>> +				    struct drm_property *prop,
>>>> +				    uint64_t val);
>>>>    int intel_plane_restore(struct drm_plane *plane);
>>>>    void intel_plane_disable(struct drm_plane *plane);
>>>>    int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>>>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>>>> index c8f744c..1ab3e11 100644
>>>> --- a/drivers/gpu/drm/i915/intel_pm.c
>>>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>>>> @@ -581,6 +581,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;
>>>> +	}
>>>>
This check is present here, so assume it is safe to remove from 
set_property.
>>>>    	/* If the kernel debugger is active, always disable compression */
>>>>    	if (in_dbg_master())
>>>> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
>>>> index 0bdb00b..ad09ba1 100644
>>>> --- a/drivers/gpu/drm/i915/intel_sprite.c
>>>> +++ b/drivers/gpu/drm/i915/intel_sprite.c
>>>> @@ -1218,12 +1218,15 @@ out_unlock:
>>>>    	return ret;
>>>>    }
>>>>
>>>> -static int intel_plane_set_property(struct drm_plane *plane,
>>>> +int intel_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;
>>>>    	int ret = -ENOENT;
>>>>
>>>> @@ -1232,6 +1235,32 @@ static int intel_plane_set_property(struct drm_plane *plane,
>>>>    		if (hweight32(val & 0xf) != 1)
>>>>    			return -EINVAL;
>>>>
>>>> +		if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
>>>> +			if (crtc == NULL)
>>>> +				return -EINVAL;
>>>> +
>>>> +			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, so disable it when rotation is not 0 and update
>>>> +				   it when rotation is set back to 0 */
>>>> +				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);
>>>> +					else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
>>>> +						mutex_lock(&dev->struct_mutex);
>>>> +						intel_update_fbc(dev);
>>>> +						mutex_unlock(&dev->struct_mutex);
>>>> +					}
>>>> +				}
>>>> +			}
>>>> +		}
>>>
>>> I think Daniel wanted to shovel all of this into
>>> intel_primary_plane_setplane().
>>>
>> I am not sure about that, Matt suggested this change and here we do
>> disable fbc for rotated plane. So, it makes more sense to keep it in
>> set_property.
>> What do you suggest?
>
> We anyway may have to disable fbc in setplace due to other factors
> (pixel format etc.) so having all the logic in the same place makes
> sense.
>
Since, update_fbc is already getting called from intel_pipe_set_base and 
we are putting a check for rotation in update_fbc (as part of this 
patch), I am removing this part from here (set_property as well as 
setplane) altogether. Will be sending the updated patch.
>>> In fact the intel_update_fbc() is already there in
>>> intel_pipe_set_base(), although I think should get moved out so that it
>>> can be placed on the correct side of intel_enable_primary_hw_plane().
>>> But that can be done as a followup later. And we also lack the
>>> disable_fbc call from intel_primary_plane_disable().
>>>
>>>> +
>>>>    		old_val = intel_plane->rotation;
>>>>    		intel_plane->rotation = val;
>>>>    		ret = intel_plane_restore(plane);
>>>> @@ -1249,7 +1278,7 @@ int intel_plane_restore(struct drm_plane *plane)
>>>>    	if (!plane->crtc || !plane->fb)
>>>>    		return 0;
>>>>
>>>> -	return intel_update_plane(plane, plane->crtc, plane->fb,
>>>> +	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
>>>>    				  intel_plane->crtc_x, intel_plane->crtc_y,
>>>>    				  intel_plane->crtc_w, intel_plane->crtc_h,
>>>>    				  intel_plane->src_x, intel_plane->src_y,
>>>> --
>>>> 1.7.10.4
>>>>
>>>> _______________________________________________
>>>> Intel-gfx mailing list
>>>> Intel-gfx@lists.freedesktop.org
>>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>>
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH] drm/i915: Add 180 degree primary plane rotation support
  2014-08-22  3:59                                   ` Jindal, Sonika
@ 2014-08-22  6:58                                     ` sonika.jindal
  2014-08-22  8:14                                     ` [PATCH 2/2] " Ville Syrjälä
  1 sibling, 0 replies; 58+ messages in thread
From: sonika.jindal @ 2014-08-22  6:58 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sagar Kamble

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.

v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
set_property(Daniel).

v11: Using same set_property function for both primary and sprite, Adding
primary plane specific code in the same function (Matt).

v12: Removing disabling/ enabling of fbc from set_property because it is done
from intel_pipe_set_base. Other formatting (Ville).

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 |   56 +++++++++++++++++++++++++++++++---
 drivers/gpu/drm/i915/intel_drv.h     |    3 ++
 drivers/gpu/drm/i915/intel_pm.c      |    6 ++++
 drivers/gpu/drm/i915/intel_sprite.c  |    4 +--
 5 files changed, 64 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 203062e..142ac52 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4214,6 +4214,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 f2a8797..241234d 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(reg, 0);
@@ -2450,8 +2453,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) {
@@ -2464,6 +2465,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 		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);
+
+		/* Finding the last pixel of the last line of the display
+		data and adding to linear_offset*/
+		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,
 		      fb->pitches[0]);
@@ -2490,6 +2506,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(reg, 0);
@@ -2538,14 +2557,28 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
 		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);
+
+			/* Finding the last pixel of the last line of the display
+			data and adding to linear_offset*/
+			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,
@@ -11717,6 +11750,7 @@ 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_plane_set_property
 };
 
 static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
@@ -11734,6 +11768,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;
 
@@ -11749,6 +11784,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d683a20..3e5d6b3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
 int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
 void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
 			       enum plane plane);
+int intel_plane_set_property(struct drm_plane *plane,
+				    struct drm_property *prop,
+				    uint64_t val);
 int intel_plane_restore(struct drm_plane *plane);
 void intel_plane_disable(struct drm_plane *plane);
 int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c8f744c..1ab3e11 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -581,6 +581,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())
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0bdb00b..be9bc21 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1218,7 +1218,7 @@ out_unlock:
 	return ret;
 }
 
-static int intel_plane_set_property(struct drm_plane *plane,
+int intel_plane_set_property(struct drm_plane *plane,
 				    struct drm_property *prop,
 				    uint64_t val)
 {
@@ -1249,7 +1249,7 @@ int intel_plane_restore(struct drm_plane *plane)
 	if (!plane->crtc || !plane->fb)
 		return 0;
 
-	return intel_update_plane(plane, plane->crtc, plane->fb,
+	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
 				  intel_plane->crtc_x, intel_plane->crtc_y,
 				  intel_plane->crtc_w, intel_plane->crtc_h,
 				  intel_plane->src_x, intel_plane->src_y,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  2014-08-22  3:59                                   ` Jindal, Sonika
  2014-08-22  6:58                                     ` [PATCH] " sonika.jindal
@ 2014-08-22  8:14                                     ` Ville Syrjälä
  2014-08-22  8:22                                       ` Jindal, Sonika
  2014-08-22  8:36                                       ` [PATCH] " sonika.jindal
  1 sibling, 2 replies; 58+ messages in thread
From: Ville Syrjälä @ 2014-08-22  8:14 UTC (permalink / raw)
  To: Jindal, Sonika; +Cc: intel-gfx, Sagar Kamble

On Fri, Aug 22, 2014 at 09:29:56AM +0530, Jindal, Sonika wrote:
> 
> 
> On 8/21/2014 7:07 PM, Ville Syrjälä wrote:
> > On Thu, Aug 21, 2014 at 05:14:35PM +0530, Jindal, Sonika wrote:
> >>
> >>
> >> On 8/21/2014 2:03 PM, Ville Syrjälä wrote:
> >>> On Thu, Aug 21, 2014 at 11:45:41AM +0530, sonika.jindal@intel.com wrote:
> >>>> 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.
> >>>>
> >>>> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
> >>>> set_property(Daniel).
> >>>>
> >>>> v11: Using same set_property function for both primary and sprite, Adding
> >>>> primary plane specific code in the same function (Matt).
> >>>>
> >>>> 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 |   57 +++++++++++++++++++++++++++++++---
> >>>>    drivers/gpu/drm/i915/intel_drv.h     |    3 ++
> >>>>    drivers/gpu/drm/i915/intel_pm.c      |    6 ++++
> >>>>    drivers/gpu/drm/i915/intel_sprite.c  |   33 ++++++++++++++++++--
> >>>>    5 files changed, 94 insertions(+), 6 deletions(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> >>>> index 203062e..142ac52 100644
> >>>> --- a/drivers/gpu/drm/i915/i915_reg.h
> >>>> +++ b/drivers/gpu/drm/i915/i915_reg.h
> >>>> @@ -4214,6 +4214,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 f2a8797..22851a9 100644
> >>>> --- a/drivers/gpu/drm/i915/intel_display.c
> >>>> +++ b/drivers/gpu/drm/i915/intel_display.c
> >>>> @@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>>>    	unsigned long linear_offset;
> >>>>    	u32 dspcntr;
> >>>>    	u32 reg = DSPCNTR(plane);
> >>>> +	int pixel_size;
> >>>> +
> >>>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> >>>>
> >>>>    	if (!intel_crtc->primary_enabled) {
> >>>>    		I915_WRITE(reg, 0);
> >>>> @@ -2411,6 +2414,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>>>    			   (intel_crtc->config.pipe_src_w - 1));
> >>>>    		I915_WRITE(DSPPOS(plane), 0);
> >>>>    	}
> >>>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
> >>>
> >>> No longer needed. We start building DSPCNTR from scratch.
> >>>
> >>>>
> >>>>    	switch (fb->pixel_format) {
> >>>>    	case DRM_FORMAT_C8:
> >>>> @@ -2450,8 +2454,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) {
> >>>> @@ -2464,6 +2466,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
> >>>>    		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);
> >>>> +
> >>>> +		/* Finding the last pixel of the last line of the display
> >>>> +		data and adding to linear_offset*/
> >>>> +		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,
> >>>>    		      fb->pitches[0]);
> >>>> @@ -2490,6 +2507,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
> >>>>    	unsigned long linear_offset;
> >>>>    	u32 dspcntr;
> >>>>    	u32 reg = DSPCNTR(plane);
> >>>> +	int pixel_size;
> >>>> +
> >>>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
> >>>>
> >>>>    	if (!intel_crtc->primary_enabled) {
> >>>>    		I915_WRITE(reg, 0);
> >>>> @@ -2505,6 +2525,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
> >>>>    	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
> >>>>    		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
> >>>>
> >>>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
> >>>> +
> >>>
> >>> ditto
> >>>
> >>>>    	switch (fb->pixel_format) {
> >>>>    	case DRM_FORMAT_C8:
> >>>>    		dspcntr |= DISPPLANE_8BPP;
> >>>> @@ -2538,14 +2560,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
> >>>>    	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
> >>>>    		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;
> >>>
> >>> Formatting looks rather wonky. In this case I think we need to
> >>> accept that we can't make it fit into 80 columns neatly and just
> >>> use longer lines.
> >>>
> >>> I would just make it:
> >>> linear_offset +=
> >>> 	(intel_crtc->config.pipe_src_h - 1) * fb->pitches[0] +
> >>> 	(intel_crtc->config.pipe_src_w - 1) * pixel_size;
> >>>
> >>> so that we have the x vs. y offsets neatly on their own lines. Same for
> >>> the other instance of this code. Or if you prefer you could to refactor
> >>> that bit of code into a small helper function.
> >>>
> >>>> +		}
> >>>> +	}
> >>>> +
> >>>> +	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,
> >>>> @@ -11717,6 +11751,7 @@ 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_plane_set_property
> >>>>    };
> >>>>
> >>>>    static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
> >>>> @@ -11734,6 +11769,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;
> >>>>
> >>>> @@ -11749,6 +11785,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> >>>> index d683a20..3e5d6b3 100644
> >>>> --- a/drivers/gpu/drm/i915/intel_drv.h
> >>>> +++ b/drivers/gpu/drm/i915/intel_drv.h
> >>>> @@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
> >>>>    int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
> >>>>    void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
> >>>>    			       enum plane plane);
> >>>> +int intel_plane_set_property(struct drm_plane *plane,
> >>>> +				    struct drm_property *prop,
> >>>> +				    uint64_t val);
> >>>>    int intel_plane_restore(struct drm_plane *plane);
> >>>>    void intel_plane_disable(struct drm_plane *plane);
> >>>>    int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
> >>>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> >>>> index c8f744c..1ab3e11 100644
> >>>> --- a/drivers/gpu/drm/i915/intel_pm.c
> >>>> +++ b/drivers/gpu/drm/i915/intel_pm.c
> >>>> @@ -581,6 +581,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;
> >>>> +	}
> >>>>
> This check is present here, so assume it is safe to remove from 
> set_property.
> >>>>    	/* If the kernel debugger is active, always disable compression */
> >>>>    	if (in_dbg_master())
> >>>> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> >>>> index 0bdb00b..ad09ba1 100644
> >>>> --- a/drivers/gpu/drm/i915/intel_sprite.c
> >>>> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> >>>> @@ -1218,12 +1218,15 @@ out_unlock:
> >>>>    	return ret;
> >>>>    }
> >>>>
> >>>> -static int intel_plane_set_property(struct drm_plane *plane,
> >>>> +int intel_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;
> >>>>    	int ret = -ENOENT;
> >>>>
> >>>> @@ -1232,6 +1235,32 @@ static int intel_plane_set_property(struct drm_plane *plane,
> >>>>    		if (hweight32(val & 0xf) != 1)
> >>>>    			return -EINVAL;
> >>>>
> >>>> +		if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
> >>>> +			if (crtc == NULL)
> >>>> +				return -EINVAL;
> >>>> +
> >>>> +			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, so disable it when rotation is not 0 and update
> >>>> +				   it when rotation is set back to 0 */
> >>>> +				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);
> >>>> +					else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
> >>>> +						mutex_lock(&dev->struct_mutex);
> >>>> +						intel_update_fbc(dev);
> >>>> +						mutex_unlock(&dev->struct_mutex);
> >>>> +					}
> >>>> +				}
> >>>> +			}
> >>>> +		}
> >>>
> >>> I think Daniel wanted to shovel all of this into
> >>> intel_primary_plane_setplane().
> >>>
> >> I am not sure about that, Matt suggested this change and here we do
> >> disable fbc for rotated plane. So, it makes more sense to keep it in
> >> set_property.
> >> What do you suggest?
> >
> > We anyway may have to disable fbc in setplace due to other factors
> > (pixel format etc.) so having all the logic in the same place makes
> > sense.
> >
> Since, update_fbc is already getting called from intel_pipe_set_base and 
> we are putting a check for rotation in update_fbc (as part of this 
> patch), I am removing this part from here (set_property as well as 
> setplane) altogether. Will be sending the updated patch.

We call update fbc too late. We need to call disable_fbc _before_
changing the rotation of plane to 180 degrees, and we need to call
update_fbc after to make sure fbc gets re-enabled if rotation is
changed back to 0. Eventually we need to refactor the update_fbc
checks a bit so that we don't have to duplicate the code for checking
this stuff.

Or someone could just take my fbc patches (or at least part of them)
which should fix it. Well those patchs probably would need some
rebasing by now. Anyways, for now I think it's enough to duplicate the
rotation check before we touch the plane and call disable_fbc when
appropriate. After changing the rotation, the current update_fbc call
is enough.

Anything beyond that amounts to actually fixing fbc. So until someone
else starts to care about fbc and either fixes it the way they like or
goes through my patches, we can accept a bit of code duplication IMO.

> >>> In fact the intel_update_fbc() is already there in
> >>> intel_pipe_set_base(), although I think should get moved out so that it
> >>> can be placed on the correct side of intel_enable_primary_hw_plane().
> >>> But that can be done as a followup later. And we also lack the
> >>> disable_fbc call from intel_primary_plane_disable().
> >>>
> >>>> +
> >>>>    		old_val = intel_plane->rotation;
> >>>>    		intel_plane->rotation = val;
> >>>>    		ret = intel_plane_restore(plane);
> >>>> @@ -1249,7 +1278,7 @@ int intel_plane_restore(struct drm_plane *plane)
> >>>>    	if (!plane->crtc || !plane->fb)
> >>>>    		return 0;
> >>>>
> >>>> -	return intel_update_plane(plane, plane->crtc, plane->fb,
> >>>> +	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
> >>>>    				  intel_plane->crtc_x, intel_plane->crtc_y,
> >>>>    				  intel_plane->crtc_w, intel_plane->crtc_h,
> >>>>    				  intel_plane->src_x, intel_plane->src_y,
> >>>> --
> >>>> 1.7.10.4
> >>>>
> >>>> _______________________________________________
> >>>> Intel-gfx mailing list
> >>>> Intel-gfx@lists.freedesktop.org
> >>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
> >>>
> >

-- 
Ville Syrjälä
Intel OTC

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH 2/2] drm/i915: Add 180 degree primary plane rotation support
  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
  1 sibling, 0 replies; 58+ messages in thread
From: Jindal, Sonika @ 2014-08-22  8:22 UTC (permalink / raw)
  To: Ville Syrjälä; +Cc: intel-gfx, Sagar Kamble



On 8/22/2014 1:44 PM, Ville Syrjälä wrote:
> On Fri, Aug 22, 2014 at 09:29:56AM +0530, Jindal, Sonika wrote:
>>
>>
>> On 8/21/2014 7:07 PM, Ville Syrjälä wrote:
>>> On Thu, Aug 21, 2014 at 05:14:35PM +0530, Jindal, Sonika wrote:
>>>>
>>>>
>>>> On 8/21/2014 2:03 PM, Ville Syrjälä wrote:
>>>>> On Thu, Aug 21, 2014 at 11:45:41AM +0530, sonika.jindal@intel.com wrote:
>>>>>> 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.
>>>>>>
>>>>>> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
>>>>>> set_property(Daniel).
>>>>>>
>>>>>> v11: Using same set_property function for both primary and sprite, Adding
>>>>>> primary plane specific code in the same function (Matt).
>>>>>>
>>>>>> 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 |   57 +++++++++++++++++++++++++++++++---
>>>>>>     drivers/gpu/drm/i915/intel_drv.h     |    3 ++
>>>>>>     drivers/gpu/drm/i915/intel_pm.c      |    6 ++++
>>>>>>     drivers/gpu/drm/i915/intel_sprite.c  |   33 ++++++++++++++++++--
>>>>>>     5 files changed, 94 insertions(+), 6 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
>>>>>> index 203062e..142ac52 100644
>>>>>> --- a/drivers/gpu/drm/i915/i915_reg.h
>>>>>> +++ b/drivers/gpu/drm/i915/i915_reg.h
>>>>>> @@ -4214,6 +4214,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 f2a8797..22851a9 100644
>>>>>> --- a/drivers/gpu/drm/i915/intel_display.c
>>>>>> +++ b/drivers/gpu/drm/i915/intel_display.c
>>>>>> @@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>>>>>     	unsigned long linear_offset;
>>>>>>     	u32 dspcntr;
>>>>>>     	u32 reg = DSPCNTR(plane);
>>>>>> +	int pixel_size;
>>>>>> +
>>>>>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>>>>>>
>>>>>>     	if (!intel_crtc->primary_enabled) {
>>>>>>     		I915_WRITE(reg, 0);
>>>>>> @@ -2411,6 +2414,7 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>>>>>     			   (intel_crtc->config.pipe_src_w - 1));
>>>>>>     		I915_WRITE(DSPPOS(plane), 0);
>>>>>>     	}
>>>>>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>>>>>
>>>>> No longer needed. We start building DSPCNTR from scratch.
>>>>>
>>>>>>
>>>>>>     	switch (fb->pixel_format) {
>>>>>>     	case DRM_FORMAT_C8:
>>>>>> @@ -2450,8 +2454,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) {
>>>>>> @@ -2464,6 +2466,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>>>>>>     		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);
>>>>>> +
>>>>>> +		/* Finding the last pixel of the last line of the display
>>>>>> +		data and adding to linear_offset*/
>>>>>> +		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,
>>>>>>     		      fb->pitches[0]);
>>>>>> @@ -2490,6 +2507,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>>>>>     	unsigned long linear_offset;
>>>>>>     	u32 dspcntr;
>>>>>>     	u32 reg = DSPCNTR(plane);
>>>>>> +	int pixel_size;
>>>>>> +
>>>>>> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>>>>>>
>>>>>>     	if (!intel_crtc->primary_enabled) {
>>>>>>     		I915_WRITE(reg, 0);
>>>>>> @@ -2505,6 +2525,8 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>>>>>     	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
>>>>>>     		dspcntr |= DISPPLANE_PIPE_CSC_ENABLE;
>>>>>>
>>>>>> +	dspcntr &= ~DISPPLANE_ROTATE_180;
>>>>>> +
>>>>>
>>>>> ditto
>>>>>
>>>>>>     	switch (fb->pixel_format) {
>>>>>>     	case DRM_FORMAT_C8:
>>>>>>     		dspcntr |= DISPPLANE_8BPP;
>>>>>> @@ -2538,14 +2560,26 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>>>>>>     	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
>>>>>>     		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;
>>>>>
>>>>> Formatting looks rather wonky. In this case I think we need to
>>>>> accept that we can't make it fit into 80 columns neatly and just
>>>>> use longer lines.
>>>>>
>>>>> I would just make it:
>>>>> linear_offset +=
>>>>> 	(intel_crtc->config.pipe_src_h - 1) * fb->pitches[0] +
>>>>> 	(intel_crtc->config.pipe_src_w - 1) * pixel_size;
>>>>>
>>>>> so that we have the x vs. y offsets neatly on their own lines. Same for
>>>>> the other instance of this code. Or if you prefer you could to refactor
>>>>> that bit of code into a small helper function.
>>>>>
>>>>>> +		}
>>>>>> +	}
>>>>>> +
>>>>>> +	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,
>>>>>> @@ -11717,6 +11751,7 @@ 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_plane_set_property
>>>>>>     };
>>>>>>
>>>>>>     static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
>>>>>> @@ -11734,6 +11769,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;
>>>>>>
>>>>>> @@ -11749,6 +11785,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
>>>>>> index d683a20..3e5d6b3 100644
>>>>>> --- a/drivers/gpu/drm/i915/intel_drv.h
>>>>>> +++ b/drivers/gpu/drm/i915/intel_drv.h
>>>>>> @@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
>>>>>>     int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
>>>>>>     void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
>>>>>>     			       enum plane plane);
>>>>>> +int intel_plane_set_property(struct drm_plane *plane,
>>>>>> +				    struct drm_property *prop,
>>>>>> +				    uint64_t val);
>>>>>>     int intel_plane_restore(struct drm_plane *plane);
>>>>>>     void intel_plane_disable(struct drm_plane *plane);
>>>>>>     int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
>>>>>> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
>>>>>> index c8f744c..1ab3e11 100644
>>>>>> --- a/drivers/gpu/drm/i915/intel_pm.c
>>>>>> +++ b/drivers/gpu/drm/i915/intel_pm.c
>>>>>> @@ -581,6 +581,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;
>>>>>> +	}
>>>>>>
>> This check is present here, so assume it is safe to remove from
>> set_property.
>>>>>>     	/* If the kernel debugger is active, always disable compression */
>>>>>>     	if (in_dbg_master())
>>>>>> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
>>>>>> index 0bdb00b..ad09ba1 100644
>>>>>> --- a/drivers/gpu/drm/i915/intel_sprite.c
>>>>>> +++ b/drivers/gpu/drm/i915/intel_sprite.c
>>>>>> @@ -1218,12 +1218,15 @@ out_unlock:
>>>>>>     	return ret;
>>>>>>     }
>>>>>>
>>>>>> -static int intel_plane_set_property(struct drm_plane *plane,
>>>>>> +int intel_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;
>>>>>>     	int ret = -ENOENT;
>>>>>>
>>>>>> @@ -1232,6 +1235,32 @@ static int intel_plane_set_property(struct drm_plane *plane,
>>>>>>     		if (hweight32(val & 0xf) != 1)
>>>>>>     			return -EINVAL;
>>>>>>
>>>>>> +		if (plane->type == DRM_PLANE_TYPE_PRIMARY) {
>>>>>> +			if (crtc == NULL)
>>>>>> +				return -EINVAL;
>>>>>> +
>>>>>> +			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, so disable it when rotation is not 0 and update
>>>>>> +				   it when rotation is set back to 0 */
>>>>>> +				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);
>>>>>> +					else if (intel_plane->rotation == BIT(DRM_ROTATE_0)) {
>>>>>> +						mutex_lock(&dev->struct_mutex);
>>>>>> +						intel_update_fbc(dev);
>>>>>> +						mutex_unlock(&dev->struct_mutex);
>>>>>> +					}
>>>>>> +				}
>>>>>> +			}
>>>>>> +		}
>>>>>
>>>>> I think Daniel wanted to shovel all of this into
>>>>> intel_primary_plane_setplane().
>>>>>
>>>> I am not sure about that, Matt suggested this change and here we do
>>>> disable fbc for rotated plane. So, it makes more sense to keep it in
>>>> set_property.
>>>> What do you suggest?
>>>
>>> We anyway may have to disable fbc in setplace due to other factors
>>> (pixel format etc.) so having all the logic in the same place makes
>>> sense.
>>>
>> Since, update_fbc is already getting called from intel_pipe_set_base and
>> we are putting a check for rotation in update_fbc (as part of this
>> patch), I am removing this part from here (set_property as well as
>> setplane) altogether. Will be sending the updated patch.
>
> We call update fbc too late. We need to call disable_fbc _before_
> changing the rotation of plane to 180 degrees, and we need to call
> update_fbc after to make sure fbc gets re-enabled if rotation is
> changed back to 0. Eventually we need to refactor the update_fbc
> checks a bit so that we don't have to duplicate the code for checking
> this stuff.
>
Ok, I'l put the disabling of fbc back in setplane.
> Or someone could just take my fbc patches (or at least part of them)
> which should fix it. Well those patchs probably would need some
> rebasing by now. Anyways, for now I think it's enough to duplicate the
> rotation check before we touch the plane and call disable_fbc when
> appropriate. After changing the rotation, the current update_fbc call
> is enough.
>
> Anything beyond that amounts to actually fixing fbc. So until someone
> else starts to care about fbc and either fixes it the way they like or
> goes through my patches, we can accept a bit of code duplication IMO.
>
>>>>> In fact the intel_update_fbc() is already there in
>>>>> intel_pipe_set_base(), although I think should get moved out so that it
>>>>> can be placed on the correct side of intel_enable_primary_hw_plane().
>>>>> But that can be done as a followup later. And we also lack the
>>>>> disable_fbc call from intel_primary_plane_disable().
>>>>>
>>>>>> +
>>>>>>     		old_val = intel_plane->rotation;
>>>>>>     		intel_plane->rotation = val;
>>>>>>     		ret = intel_plane_restore(plane);
>>>>>> @@ -1249,7 +1278,7 @@ int intel_plane_restore(struct drm_plane *plane)
>>>>>>     	if (!plane->crtc || !plane->fb)
>>>>>>     		return 0;
>>>>>>
>>>>>> -	return intel_update_plane(plane, plane->crtc, plane->fb,
>>>>>> +	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
>>>>>>     				  intel_plane->crtc_x, intel_plane->crtc_y,
>>>>>>     				  intel_plane->crtc_w, intel_plane->crtc_h,
>>>>>>     				  intel_plane->src_x, intel_plane->src_y,
>>>>>> --
>>>>>> 1.7.10.4
>>>>>>
>>>>>> _______________________________________________
>>>>>> Intel-gfx mailing list
>>>>>> Intel-gfx@lists.freedesktop.org
>>>>>> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
>>>>>
>>>
>

^ permalink raw reply	[flat|nested] 58+ messages in thread

* [PATCH] drm/i915: Add 180 degree primary plane rotation support
  2014-08-22  8:14                                     ` [PATCH 2/2] " Ville Syrjälä
  2014-08-22  8:22                                       ` Jindal, Sonika
@ 2014-08-22  8:36                                       ` sonika.jindal
  2014-08-25 20:50                                         ` Daniel Vetter
  1 sibling, 1 reply; 58+ messages in thread
From: sonika.jindal @ 2014-08-22  8:36 UTC (permalink / raw)
  To: intel-gfx; +Cc: Sagar Kamble

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.

v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
set_property(Daniel).

v11: Using same set_property function for both primary and sprite, Adding
primary plane specific code in the same function (Matt).

v12: Removing disabling/ enabling of fbc from set_property because it is done
from intel_pipe_set_base. Other formatting

v13: we need to call disable_fbc before changing the rotation to 180,
disable_fbc from intel_pipe_set_base gets called very late, that will
be used to re-enable fbc if rotation is set to 0 (Ville).

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 |   69 ++++++++++++++++++++++++++++++++--
 drivers/gpu/drm/i915/intel_drv.h     |    3 ++
 drivers/gpu/drm/i915/intel_pm.c      |    6 +++
 drivers/gpu/drm/i915/intel_sprite.c  |    4 +-
 5 files changed, 77 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 203062e..142ac52 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4214,6 +4214,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 f2a8797..0c77438 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(reg, 0);
@@ -2450,8 +2453,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) {
@@ -2464,6 +2465,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
 		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);
+
+		/* Finding the last pixel of the last line of the display
+		data and adding to linear_offset*/
+		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,
 		      fb->pitches[0]);
@@ -2490,6 +2506,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	unsigned long linear_offset;
 	u32 dspcntr;
 	u32 reg = DSPCNTR(plane);
+	int pixel_size;
+
+	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
 
 	if (!intel_crtc->primary_enabled) {
 		I915_WRITE(reg, 0);
@@ -2538,14 +2557,28 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
 	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
 		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);
+
+			/* Finding the last pixel of the last line of the display
+			data and adding to linear_offset*/
+			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,
@@ -11572,6 +11605,7 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
 			     uint32_t src_w, uint32_t src_h)
 {
 	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
 	struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
@@ -11684,6 +11718,18 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
 		mutex_unlock(&dev->struct_mutex);
 
 	} else {
+		if (intel_crtc && intel_crtc->active &&
+				intel_crtc->primary_enabled) {
+
+			/* FBC does not work on some platforms for rotated
+			   planes, so disable it when rotation is not 0 and update
+			   it when rotation is set back to 0 */
+			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);
+			}
+		}
 		ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
 		if (ret)
 			return ret;
@@ -11717,6 +11763,7 @@ 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_plane_set_property
 };
 
 static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
@@ -11734,6 +11781,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;
 
@@ -11749,6 +11797,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index d683a20..3e5d6b3 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
 int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
 void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
 			       enum plane plane);
+int intel_plane_set_property(struct drm_plane *plane,
+				    struct drm_property *prop,
+				    uint64_t val);
 int intel_plane_restore(struct drm_plane *plane);
 void intel_plane_disable(struct drm_plane *plane);
 int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c8f744c..1ab3e11 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -581,6 +581,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())
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index 0bdb00b..be9bc21 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -1218,7 +1218,7 @@ out_unlock:
 	return ret;
 }
 
-static int intel_plane_set_property(struct drm_plane *plane,
+int intel_plane_set_property(struct drm_plane *plane,
 				    struct drm_property *prop,
 				    uint64_t val)
 {
@@ -1249,7 +1249,7 @@ int intel_plane_restore(struct drm_plane *plane)
 	if (!plane->crtc || !plane->fb)
 		return 0;
 
-	return intel_update_plane(plane, plane->crtc, plane->fb,
+	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
 				  intel_plane->crtc_x, intel_plane->crtc_y,
 				  intel_plane->crtc_w, intel_plane->crtc_h,
 				  intel_plane->src_x, intel_plane->src_y,
-- 
1.7.10.4

^ permalink raw reply related	[flat|nested] 58+ messages in thread

* Re: [PATCH 1/2] drm/i915: Updating plane parameters for primary plane in setplane
  2014-08-21  6:14                           ` sonika.jindal
@ 2014-08-25 20:42                             ` Daniel Vetter
  0 siblings, 0 replies; 58+ messages in thread
From: Daniel Vetter @ 2014-08-25 20:42 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx

On Thu, Aug 21, 2014 at 11:44:39AM +0530, sonika.jindal@intel.com wrote:
> From: Sonika Jindal <sonika.jindal@intel.com>
> 
> v2: Moving setting of plane members in the end to take care of failure cases and
> not-visible cases (Matt).
> 
> Signed-off-by: Sonika Jindal <sonika.jindal@intel.com>

Queued for -next, thanks for the patch.

But please when submitting anything non-trival (i.e. "fix typo" or similar
simple stuff) a proper commit message to explain the motivation for a
patch is required. I've added a small blurb for this one here, but
guessing at why a patch is necessary is much harder than just reading the
explanation. Please double-check the commit patch to make sure I've
actually understood it correctly.

Thanks, Daniel
> ---
>  drivers/gpu/drm/i915/intel_display.c |   38 +++++++++++++++++++++++++++-------
>  1 file changed, 31 insertions(+), 7 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
> index 0b327eb..f2a8797 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -11594,6 +11594,21 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
>  		.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0,
>  		.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0,
>  	};
> +	const struct {
> +		int crtc_x, crtc_y;
> +		unsigned int crtc_w, crtc_h;
> +		uint32_t src_x, src_y, src_w, src_h;
> +	} orig = {
> +		.crtc_x = crtc_x,
> +		.crtc_y = crtc_y,
> +		.crtc_w = crtc_w,
> +		.crtc_h = crtc_h,
> +		.src_x = src_x,
> +		.src_y = src_y,
> +		.src_w = src_w,
> +		.src_h = src_h,
> +	};
> +	struct intel_plane *intel_plane = to_intel_plane(plane);
>  	bool visible;
>  	int ret;
>  
> @@ -11668,15 +11683,24 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
>  
>  		mutex_unlock(&dev->struct_mutex);
>  
> -		return 0;
> -	}
> +	} else {
> +		ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
> +		if (ret)
> +			return ret;
>  
> -	ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
> -	if (ret)
> -		return ret;
> +		if (!intel_crtc->primary_enabled)
> +			intel_enable_primary_hw_plane(plane, crtc);
> +	}
>  
> -	if (!intel_crtc->primary_enabled)
> -		intel_enable_primary_hw_plane(plane, crtc);
> +	intel_plane->crtc_x = orig.crtc_x;
> +	intel_plane->crtc_y = orig.crtc_y;
> +	intel_plane->crtc_w = orig.crtc_w;
> +	intel_plane->crtc_h = orig.crtc_h;
> +	intel_plane->src_x = orig.src_x;
> +	intel_plane->src_y = orig.src_y;
> +	intel_plane->src_w = orig.src_w;
> +	intel_plane->src_h = orig.src_h;
> +	intel_plane->obj = obj;
>  
>  	return 0;
>  }
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

* Re: [PATCH] drm/i915: Add 180 degree primary plane rotation support
  2014-08-22  8:36                                       ` [PATCH] " sonika.jindal
@ 2014-08-25 20:50                                         ` Daniel Vetter
  0 siblings, 0 replies; 58+ messages in thread
From: Daniel Vetter @ 2014-08-25 20:50 UTC (permalink / raw)
  To: sonika.jindal; +Cc: intel-gfx, Sagar Kamble

On Fri, Aug 22, 2014 at 02:06:04PM +0530, sonika.jindal@intel.com wrote:
> 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.
> 
> v10: Calling intel_primary_plane_setplane instead of update_primary_plane in
> set_property(Daniel).
> 
> v11: Using same set_property function for both primary and sprite, Adding
> primary plane specific code in the same function (Matt).
> 
> v12: Removing disabling/ enabling of fbc from set_property because it is done
> from intel_pipe_set_base. Other formatting
> 
> v13: we need to call disable_fbc before changing the rotation to 180,
> disable_fbc from intel_pipe_set_base gets called very late, that will
> be used to re-enable fbc if rotation is set to 0 (Ville).
> 
> 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>

Queued for -next, thanks for the patch. I've added a FIXME to the
disable_fbc so that we know there's some work left to do in the future.

And I've polished the coding style a bit in some places (function argument
alignement, comment style and folding int some nested if clauses).
-Daniel
> ---
>  drivers/gpu/drm/i915/i915_reg.h      |    1 +
>  drivers/gpu/drm/i915/intel_display.c |   69 ++++++++++++++++++++++++++++++++--
>  drivers/gpu/drm/i915/intel_drv.h     |    3 ++
>  drivers/gpu/drm/i915/intel_pm.c      |    6 +++
>  drivers/gpu/drm/i915/intel_sprite.c  |    4 +-
>  5 files changed, 77 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 203062e..142ac52 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -4214,6 +4214,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 f2a8797..0c77438 100644
> --- a/drivers/gpu/drm/i915/intel_display.c
> +++ b/drivers/gpu/drm/i915/intel_display.c
> @@ -2384,6 +2384,9 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  	unsigned long linear_offset;
>  	u32 dspcntr;
>  	u32 reg = DSPCNTR(plane);
> +	int pixel_size;
> +
> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>  
>  	if (!intel_crtc->primary_enabled) {
>  		I915_WRITE(reg, 0);
> @@ -2450,8 +2453,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) {
> @@ -2464,6 +2465,21 @@ static void i9xx_update_primary_plane(struct drm_crtc *crtc,
>  		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);
> +
> +		/* Finding the last pixel of the last line of the display
> +		data and adding to linear_offset*/
> +		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,
>  		      fb->pitches[0]);
> @@ -2490,6 +2506,9 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  	unsigned long linear_offset;
>  	u32 dspcntr;
>  	u32 reg = DSPCNTR(plane);
> +	int pixel_size;
> +
> +	pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
>  
>  	if (!intel_crtc->primary_enabled) {
>  		I915_WRITE(reg, 0);
> @@ -2538,14 +2557,28 @@ static void ironlake_update_primary_plane(struct drm_crtc *crtc,
>  	if (!IS_HASWELL(dev) && !IS_BROADWELL(dev))
>  		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);
> +
> +			/* Finding the last pixel of the last line of the display
> +			data and adding to linear_offset*/
> +			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,
> @@ -11572,6 +11605,7 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
>  			     uint32_t src_w, uint32_t src_h)
>  {
>  	struct drm_device *dev = crtc->dev;
> +	struct drm_i915_private *dev_priv = dev->dev_private;
>  	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
>  	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
>  	struct drm_i915_gem_object *old_obj = intel_fb_obj(plane->fb);
> @@ -11684,6 +11718,18 @@ intel_primary_plane_setplane(struct drm_plane *plane, struct drm_crtc *crtc,
>  		mutex_unlock(&dev->struct_mutex);
>  
>  	} else {
> +		if (intel_crtc && intel_crtc->active &&
> +				intel_crtc->primary_enabled) {
> +
> +			/* FBC does not work on some platforms for rotated
> +			   planes, so disable it when rotation is not 0 and update
> +			   it when rotation is set back to 0 */
> +			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);
> +			}
> +		}
>  		ret = intel_pipe_set_base(crtc, src.x1, src.y1, fb);
>  		if (ret)
>  			return ret;
> @@ -11717,6 +11763,7 @@ 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_plane_set_property
>  };
>  
>  static struct drm_plane *intel_primary_plane_create(struct drm_device *dev,
> @@ -11734,6 +11781,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;
>  
> @@ -11749,6 +11797,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_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index d683a20..3e5d6b3 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -1093,6 +1093,9 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob);
>  int intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane);
>  void intel_flush_primary_plane(struct drm_i915_private *dev_priv,
>  			       enum plane plane);
> +int intel_plane_set_property(struct drm_plane *plane,
> +				    struct drm_property *prop,
> +				    uint64_t val);
>  int intel_plane_restore(struct drm_plane *plane);
>  void intel_plane_disable(struct drm_plane *plane);
>  int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
> diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
> index c8f744c..1ab3e11 100644
> --- a/drivers/gpu/drm/i915/intel_pm.c
> +++ b/drivers/gpu/drm/i915/intel_pm.c
> @@ -581,6 +581,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())
> diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
> index 0bdb00b..be9bc21 100644
> --- a/drivers/gpu/drm/i915/intel_sprite.c
> +++ b/drivers/gpu/drm/i915/intel_sprite.c
> @@ -1218,7 +1218,7 @@ out_unlock:
>  	return ret;
>  }
>  
> -static int intel_plane_set_property(struct drm_plane *plane,
> +int intel_plane_set_property(struct drm_plane *plane,
>  				    struct drm_property *prop,
>  				    uint64_t val)
>  {
> @@ -1249,7 +1249,7 @@ int intel_plane_restore(struct drm_plane *plane)
>  	if (!plane->crtc || !plane->fb)
>  		return 0;
>  
> -	return intel_update_plane(plane, plane->crtc, plane->fb,
> +	return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
>  				  intel_plane->crtc_x, intel_plane->crtc_y,
>  				  intel_plane->crtc_w, intel_plane->crtc_h,
>  				  intel_plane->src_x, intel_plane->src_y,
> -- 
> 1.7.10.4
> 
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx

-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 58+ messages in thread

end of thread, other threads:[~2014-08-25 20:50 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 5/6] drm/i915: Add 180 degree primary plane rotation support sonika.jindal
2014-07-15  9:11   ` 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

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.