[PATCH RFC 7/8] drm/i915: add 'rotation' CRTC property

Paulo Zanoni przanoni at gmail.com
Thu Mar 29 14:27:25 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
v3: adapt to the new drm code for object properties

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(-)

After talking to Rob we concluded that instead of having a value from 0-359 we
should have a bitmask (just like X's RR_Rotate_X stuff). This will allow not
only rotations, but also reflections. OTOH, rotations that are not 0, 90, 180 or
270 will not be allowed. If we ever need these arbitrary rotations, I think
we should create a property that matches X's transformation matrix and keep this
one existing (just like X).

Rob plans to implement "bit mask properties" support, so after his patch I'll
update this one to use a bit mask property.

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index c0f19f5..98d7d74 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -779,6 +779,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 f59cd3a..ca99450 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 72b292a..d621a54 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7626,6 +7626,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,
@@ -7644,8 +7688,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_object_attach_property(&crtc->base, prop, 0);
+}
+
 static void intel_crtc_init(struct drm_device *dev, int pipe)
 {
 	drm_i915_private_t *dev_priv = dev->dev_private;
@@ -7665,6 +7728,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