Blame SOURCES/0005-drm-Reset-primary-plane-rotation-to-DRM_MODE_ROTATE_.patch

a802d9
From d769f1194c934ed4ff7ce6bfc502ba485d461c12 Mon Sep 17 00:00:00 2001
a802d9
From: Hans de Goede <hdegoede@redhat.com>
a802d9
Date: Sat, 20 Jan 2018 12:20:29 +0100
a802d9
Subject: [PATCH 5/6] drm: Reset primary plane rotation to DRM_MODE_ROTATE_0
a802d9
a802d9
On devices where the (LCD) panel is mounted upside-down in the case
a802d9
the kernel's drm_fb_helper code may have set up rotation on the primary
a802d9
plane to make the text-console (and other fbdev using apps) show the right
a802d9
way up.
a802d9
a802d9
We inherit this rotation from the text-mode and since we do our own rotation
a802d9
where necessary we end up rotating twice and showing the boot-splash
a802d9
upside-down again.
a802d9
a802d9
Dealing with hardware rotation may require using a specific framebuffer
a802d9
tiling which we do not support, so we should just disable the hardware
a802d9
rotation and keep using our own software rotation.
a802d9
a802d9
This commit adds code to find the primary plane and its rotation property
a802d9
and if it is not DRM_MODE_ROTATE_0 then sets it to DRM_MODE_ROTATE_0. fixing
a802d9
the double rotation issue.
a802d9
a802d9
https://bugs.freedesktop.org/show_bug.cgi?id=104714
a802d9
---
a802d9
 src/plugins/renderers/drm/plugin.c | 86 ++++++++++++++++++++++++++++++
a802d9
 1 file changed, 86 insertions(+)
a802d9
a802d9
diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c
a802d9
index f495854..fb79aa6 100644
a802d9
--- a/src/plugins/renderers/drm/plugin.c
a802d9
+++ b/src/plugins/renderers/drm/plugin.c
a802d9
@@ -43,6 +43,7 @@
a802d9
 #include <unistd.h>
a802d9
 
a802d9
 #include <drm.h>
a802d9
+#include <drm_mode.h>
a802d9
 #include <xf86drm.h>
a802d9
 #include <xf86drmMode.h>
a802d9
 
a802d9
@@ -62,6 +63,11 @@
a802d9
 
a802d9
 #define BYTES_PER_PIXEL (4)
a802d9
 
a802d9
+/* For builds with libdrm < 2.4.89 */
a802d9
+#ifndef DRM_MODE_ROTATE_0
a802d9
+#define DRM_MODE_ROTATE_0 (1<<0)
a802d9
+#endif
a802d9
+
a802d9
 struct _ply_renderer_head
a802d9
 {
a802d9
         ply_renderer_backend_t *backend;
a802d9
@@ -499,6 +505,85 @@ ply_renderer_head_free (ply_renderer_head_t *head)
a802d9
         free (head);
a802d9
 }
a802d9
 
a802d9
+static void
a802d9
+ply_renderer_head_clear_plane_rotation (ply_renderer_backend_t *backend,
a802d9
+                                        ply_renderer_head_t    *head)
a802d9
+{
a802d9
+        drmModeObjectPropertiesPtr plane_props;
a802d9
+        drmModePlaneResPtr plane_resources;
a802d9
+        drmModePropertyPtr prop;
a802d9
+        drmModePlanePtr plane;
a802d9
+        uint64_t rotation;
a802d9
+        uint32_t i, j;
a802d9
+        int rotation_prop_id = -1;
a802d9
+        int primary_id = -1;
a802d9
+        int err;
a802d9
+
a802d9
+        err = drmSetClientCap (backend->device_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
a802d9
+        if (err)
a802d9
+                return;
a802d9
+
a802d9
+        plane_resources = drmModeGetPlaneResources (backend->device_fd);
a802d9
+        if (!plane_resources)
a802d9
+                return;
a802d9
+
a802d9
+        for (i = 0; i < plane_resources->count_planes; i++) {
a802d9
+                plane = drmModeGetPlane (backend->device_fd,
a802d9
+                                         plane_resources->planes[i]);
a802d9
+                if (!plane)
a802d9
+                        continue;
a802d9
+
a802d9
+                if (plane->crtc_id != head->controller_id) {
a802d9
+                        drmModeFreePlane (plane);
a802d9
+                        continue;
a802d9
+                }
a802d9
+
a802d9
+                plane_props = drmModeObjectGetProperties (backend->device_fd,
a802d9
+                                                          plane->plane_id,
a802d9
+                                                          DRM_MODE_OBJECT_PLANE);
a802d9
+
a802d9
+                for (j = 0; plane_props && (j < plane_props->count_props); j++) {
a802d9
+                        prop = drmModeGetProperty (backend->device_fd,
a802d9
+                                                   plane_props->props[j]);
a802d9
+                        if (!prop)
a802d9
+                                continue;
a802d9
+
a802d9
+                        if (strcmp (prop->name, "type") == 0 &&
a802d9
+                            plane_props->prop_values[j] == DRM_PLANE_TYPE_PRIMARY) {
a802d9
+                                primary_id = plane->plane_id;
a802d9
+                        }
a802d9
+
a802d9
+                        if (strcmp (prop->name, "rotation") == 0) {
a802d9
+                                rotation_prop_id = plane_props->props[j];
a802d9
+                                rotation = plane_props->prop_values[j];
a802d9
+                        }
a802d9
+
a802d9
+                        drmModeFreeProperty (prop);
a802d9
+                }
a802d9
+
a802d9
+                drmModeFreeObjectProperties (plane_props);
a802d9
+                drmModeFreePlane (plane);
a802d9
+
a802d9
+                if (primary_id != -1)
a802d9
+                        break;
a802d9
+
a802d9
+                /* Not primary -> clear any found rotation property */
a802d9
+                rotation_prop_id = -1;
a802d9
+        }
a802d9
+
a802d9
+        if (primary_id != -1 && rotation_prop_id != -1 && rotation != DRM_MODE_ROTATE_0) {
a802d9
+                err = drmModeObjectSetProperty (backend->device_fd,
a802d9
+                                                primary_id,
a802d9
+                                                DRM_MODE_OBJECT_PLANE,
a802d9
+                                                rotation_prop_id,
a802d9
+                                                DRM_MODE_ROTATE_0);
a802d9
+                ply_trace ("Cleared rotation on primary plane %d result %d",
a802d9
+                           primary_id, err);
a802d9
+        }
a802d9
+
a802d9
+        drmModeFreePlaneResources (plane_resources);
a802d9
+}
a802d9
+
a802d9
 static bool
a802d9
 ply_renderer_head_set_scan_out_buffer (ply_renderer_backend_t *backend,
a802d9
                                        ply_renderer_head_t    *head,
a802d9
@@ -525,6 +610,7 @@ ply_renderer_head_set_scan_out_buffer (ply_renderer_backend_t *backend,
a802d9
                 return false;
a802d9
         }
a802d9
 
a802d9
+        ply_renderer_head_clear_plane_rotation (backend, head);
a802d9
         return true;
a802d9
 }
a802d9
 
a802d9
-- 
a802d9
2.17.0
a802d9