[PATCH 4/5] drm/i915: add 'rotation' CRTC property

Paulo Zanoni przanoni at gmail.com
Tue Mar 20 07:48:31 PDT 2012


From: Paulo Zanoni <paulo.r.zanoni at intel.com>

This property is needed so we can inform the KVMr feature about our
current rotation: whenever we change the rotation, we should change
that property so that the KVMr knows that the screen is rotated.

How to reproduce the problem:
- on an AMT machine, enable KVM
- boot the machine, use xrandr to rotate the display
- use VNC to connect to the KVM
- try to use the mouse

v2: only create the property once

Signed-off-by: Paulo Zanoni <paulo.r.zanoni at intel.com>
---
 drivers/gpu/drm/i915/i915_drv.h      |    1 +
 drivers/gpu/drm/i915/i915_reg.h      |    5 +++
 drivers/gpu/drm/i915/intel_display.c |   66 ++++++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index e7a00b7..7994c4f 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -780,6 +780,7 @@ typedef struct drm_i915_private {
 
 	struct drm_property *broadcast_rgb_property;
 	struct drm_property *force_audio_property;
+	struct drm_property *rotation_property;
 } drm_i915_private_t;
 
 enum hdmi_force_audio {
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 52a06be..79e8b12 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -2407,6 +2407,11 @@
 #define   PIPECONF_INTERLACED_DBL_ILK		(4 << 21) /* ilk/snb only */
 #define   PIPECONF_PFIT_PF_INTERLACED_DBL_ILK	(5 << 21) /* ilk/snb only */
 #define   PIPECONF_CXSR_DOWNCLOCK	(1<<16)
+#define   PIPECONF_ROTATION_MASK	(3 << 14)
+#define   PIPECONF_ROTATION_0	(0 << 14)
+#define   PIPECONF_ROTATION_90	(1 << 14)
+#define   PIPECONF_ROTATION_180	(2 << 14)
+#define   PIPECONF_ROTATION_270	(3 << 14)
 #define   PIPECONF_BPP_MASK	(0x000000e0)
 #define   PIPECONF_BPP_8	(0<<5)
 #define   PIPECONF_BPP_10	(1<<5)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 683002fb..4842de8 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7625,6 +7625,50 @@ static void intel_crtc_reset(struct drm_crtc *crtc)
 	intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane);
 }
 
+static void intel_crtc_set_rotation(struct drm_crtc *crtc,
+				    uint64_t rotation)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+	int reg = PIPECONF(intel_crtc->pipe);
+	u32 val = I915_READ(reg);
+
+	val &= ~PIPECONF_ROTATION_MASK;
+
+	switch (rotation) {
+	case 0:
+		val |= PIPECONF_ROTATION_0;
+		break;
+	case 90:
+		val |= PIPECONF_ROTATION_90;
+		break;
+	case 180:
+		val |= PIPECONF_ROTATION_180;
+		break;
+	case 270:
+		val |= PIPECONF_ROTATION_270;
+		break;
+	default:
+		DRM_ERROR("Unsupported rotation: %Lu\n", rotation);
+		val |= PIPECONF_ROTATION_0;
+	}
+
+	I915_WRITE(reg, val);
+}
+
+static int intel_crtc_set_property(struct drm_crtc *crtc,
+				   struct drm_property *property,
+				   uint64_t val)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+
+	if (property == dev_priv->rotation_property)
+		intel_crtc_set_rotation(crtc, val);
+	return 0;
+}
+
 static struct drm_crtc_helper_funcs intel_helper_funcs = {
 	.dpms = intel_crtc_dpms,
 	.mode_fixup = intel_crtc_mode_fixup,
@@ -7643,8 +7687,27 @@ static const struct drm_crtc_funcs intel_crtc_funcs = {
 	.set_config = drm_crtc_helper_set_config,
 	.destroy = intel_crtc_destroy,
 	.page_flip = intel_crtc_page_flip,
+	.set_property = intel_crtc_set_property,
 };
 
+static void intel_attach_rotation_property(struct drm_crtc *crtc)
+{
+	struct drm_device *dev = crtc->dev;
+	struct drm_i915_private *dev_priv = dev->dev_private;
+	struct drm_property *prop;
+
+	prop = dev_priv->rotation_property;
+	if (prop == NULL) {
+		prop = drm_property_create_range(dev, 0, "rotation", 0, 359);
+		if (prop == NULL)
+			return;
+
+		dev_priv->rotation_property = prop;
+	}
+
+	drm_crtc_attach_property(crtc, prop, 0);
+}
+
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -7664,6 +7727,9 @@ static void intel_crtc_init(struct drm_device *dev, int pipe)
 		intel_crtc->lut_b[i] = i;
 	}
 
+	if (INTEL_INFO(dev)->gen >= 5)
+		intel_attach_rotation_property(&intel_crtc->base);
+
 	/* Swap pipes & planes for FBC on pre-965 */
 	intel_crtc->pipe = pipe;
 	intel_crtc->plane = pipe;
-- 
1.7.9.1



More information about the dri-devel mailing list