From: Paulo Zanoni <paulo.r.zan...@intel.com>

Don't worry if that fails: only the KVMr feature will be affected.

We still need to change the sna/ code.
We also need to add the dependency on libdrm.

Signed-off-by: Paulo Zanoni <paulo.r.zan...@intel.com>
---
 src/intel.h         |    3 ++
 src/intel_display.c |   80 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/intel_driver.c  |    2 +
 3 files changed, 85 insertions(+), 0 deletions(-)

This is just an RFC. Read comment from Kernel patch 0007.

diff --git a/src/intel.h b/src/intel.h
index f806aea..29df531 100644
--- a/src/intel.h
+++ b/src/intel.h
@@ -644,4 +644,7 @@ static inline Bool intel_pixmap_is_offscreen(PixmapPtr 
pixmap)
        return priv && priv->offscreen;
 }
 
+/* intel_display.c */
+void intel_crtc_leave_vt(ScrnInfoPtr scrn);
+
 #endif /* _I830_H_ */
diff --git a/src/intel_display.c b/src/intel_display.c
index abdc372..0dd85b8 100644
--- a/src/intel_display.c
+++ b/src/intel_display.c
@@ -82,6 +82,7 @@ struct intel_crtc {
        uint32_t rotate_fb_id;
        xf86CrtcPtr crtc;
        struct list link;
+       drmModePropertyPtr rotation_prop;
 };
 
 struct intel_property {
@@ -418,6 +419,44 @@ done:
        return ret;
 }
 
+static void
+intel_crtc_inform_rotation(xf86CrtcPtr crtc, Rotation rotation)
+{
+       struct intel_crtc *intel_crtc = crtc->driver_private;
+       int ret, int_rotation;
+
+       /* Try to inform the Kernel about our current rotation but don't
+        * worry if that fails */
+       if (!intel_crtc->rotation_prop)
+               return;
+
+       switch (rotation) {
+       case RR_Rotate_0:
+               int_rotation = 0;
+               break;
+       case RR_Rotate_90:
+               int_rotation = 90;
+               break;
+       case RR_Rotate_180:
+               int_rotation = 180;
+               break;
+       case RR_Rotate_270:
+               int_rotation = 270;
+               break;
+       default:
+               int_rotation = 0;
+       }
+
+       ret = drmModeObjectSetProperty(intel_crtc->mode->fd,
+                                      crtc_id(intel_crtc),
+                                      DRM_MODE_OBJECT_CRTC,
+                                      intel_crtc->rotation_prop->prop_id,
+                                      int_rotation);
+       if (ret)
+               xf86DrvMsg(crtc->scrn->scrnIndex, X_WARNING,
+                          "Failed to set CRTC rotation: %s\n", strerror(-ret));
+}
+
 static Bool
 intel_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
                          Rotation rotation, int x, int y)
@@ -464,6 +503,8 @@ intel_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr 
mode,
                crtc->y = saved_y;
                crtc->rotation = saved_rotation;
                crtc->mode = saved_mode;
+       } else {
+               intel_crtc_inform_rotation(crtc, rotation);
        }
        return ret;
 }
@@ -640,12 +681,49 @@ intel_crtc_destroy(xf86CrtcPtr crtc)
                intel_crtc->cursor = NULL;
        }
 
+       if (intel_crtc->rotation_prop)
+               drmModeFreeProperty(intel_crtc->rotation_prop);
+
        list_del(&intel_crtc->link);
        free(intel_crtc);
 
        crtc->driver_private = NULL;
 }
 
+static void
+intel_crtc_load_properties(struct intel_mode *mode,
+                          struct intel_crtc *crtc)
+{
+       unsigned int i;
+       drmModeObjectPropertiesPtr props;
+       drmModePropertyPtr prop;
+
+       crtc->rotation_prop = NULL;
+
+       props = drmModeObjectGetProperties(mode->fd, crtc_id(crtc),
+                                          DRM_MODE_OBJECT_CRTC);
+       if (props) {
+               for (i = 0; i < props->count_props; i++) {
+                       prop = drmModeGetProperty(mode->fd, props->props[i]);
+                       if (!strcmp(prop->name, "rotation"))
+                               crtc->rotation_prop = prop;
+                       else
+                               drmModeFreeProperty(prop);
+               }
+               drmModeFreeObjectProperties(props);
+       }
+}
+
+void
+intel_crtc_leave_vt(ScrnInfoPtr scrn)
+{
+       int i;
+       xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+
+       for (i = 0; i < xf86_config->num_crtc; i++)
+               intel_crtc_inform_rotation(xf86_config->crtc[i], RR_Rotate_0);
+}
+
 static const xf86CrtcFuncsRec intel_crtc_funcs = {
        .dpms = intel_crtc_dpms,
        .set_mode_major = intel_crtc_set_mode_major,
@@ -692,6 +770,8 @@ intel_crtc_init(ScrnInfoPtr scrn, struct intel_mode *mode, 
int num)
 
        intel_crtc->crtc = crtc;
        list_add(&intel_crtc->link, &mode->crtcs);
+
+       intel_crtc_load_properties(mode, intel_crtc);
 }
 
 static Bool
diff --git a/src/intel_driver.c b/src/intel_driver.c
index 4265de8..98466a3 100644
--- a/src/intel_driver.c
+++ b/src/intel_driver.c
@@ -1115,6 +1115,8 @@ static void I830LeaveVT(int scrnIndex, int flags)
        intel_screen_private *intel = intel_get_screen_private(scrn);
        int ret;
 
+       intel_crtc_leave_vt(scrn);
+
        xf86RotateFreeShadow(scrn);
 
        xf86_hide_cursors(scrn);
-- 
1.7.9.1

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to