backend-drm: Parse KMS panel orientation property, apply to weston_head
authorLucas Stach <l.stach@pengutronix.de>
Mon, 25 Nov 2019 23:31:57 +0000 (23:31 +0000)
committerDaniel Stone <daniels@collabora.com>
Fri, 6 Mar 2020 21:50:38 +0000 (21:50 +0000)
The KMS 'panel orientation' property allows the driver to statically
declare a fixed rotation of an output device. Now that weston_head has a
transform member, plumb the KMS property through to weston_head so the
compositor can make a smarter choice out of the box.

Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
[daniels: Extracted from one of Lucas's patches]
Signed-off-by: Daniel Stone <daniels@collabora.com>
libweston/backend-drm/drm-internal.h
libweston/backend-drm/kms.c
libweston/backend-drm/modes.c

index 2384a9a..855baf1 100644 (file)
@@ -200,6 +200,7 @@ enum wdrm_connector_property {
        WDRM_CONNECTOR_NON_DESKTOP,
        WDRM_CONNECTOR_CONTENT_PROTECTION,
        WDRM_CONNECTOR_HDCP_CONTENT_TYPE,
+       WDRM_CONNECTOR_PANEL_ORIENTATION,
        WDRM_CONNECTOR__COUNT
 };
 
@@ -224,6 +225,14 @@ enum wdrm_dpms_state {
        WDRM_DPMS_STATE__COUNT
 };
 
+enum wdrm_panel_orientation {
+       WDRM_PANEL_ORIENTATION_NORMAL = 0,
+       WDRM_PANEL_ORIENTATION_UPSIDE_DOWN,
+       WDRM_PANEL_ORIENTATION_LEFT_SIDE_UP,
+       WDRM_PANEL_ORIENTATION_RIGHT_SIDE_UP,
+       WDRM_PANEL_ORIENTATION__COUNT
+};
+
 /**
  * List of properties attached to DRM CRTCs
  */
index 192435c..7576c00 100644 (file)
@@ -116,6 +116,13 @@ struct drm_property_enum_info hdcp_content_type_enums[] = {
        },
 };
 
+struct drm_property_enum_info panel_orientation_enums[] = {
+       [WDRM_PANEL_ORIENTATION_NORMAL] = { .name = "Normal", },
+       [WDRM_PANEL_ORIENTATION_UPSIDE_DOWN] = { .name = "Upside Down", },
+       [WDRM_PANEL_ORIENTATION_LEFT_SIDE_UP] = { .name = "Left Side Up", },
+       [WDRM_PANEL_ORIENTATION_RIGHT_SIDE_UP] = { .name = "Right Side Up", },
+};
+
 const struct drm_property_info connector_props[] = {
        [WDRM_CONNECTOR_EDID] = { .name = "EDID" },
        [WDRM_CONNECTOR_DPMS] = {
@@ -135,6 +142,11 @@ const struct drm_property_info connector_props[] = {
                .enum_values = hdcp_content_type_enums,
                .num_enum_values = WDRM_HDCP_CONTENT_TYPE__COUNT,
        },
+       [WDRM_CONNECTOR_PANEL_ORIENTATION] = {
+               .name = "panel orientation",
+               .enum_values = panel_orientation_enums,
+               .num_enum_values = WDRM_PANEL_ORIENTATION__COUNT,
+       },
 };
 
 const struct drm_property_info crtc_props[] = {
index e12ed62..69611b0 100644 (file)
@@ -128,6 +128,29 @@ check_non_desktop(struct drm_head *head, drmModeObjectPropertiesPtr props)
        return drm_property_get_value(non_desktop_info, props, 0);
 }
 
+static uint32_t
+get_panel_orientation(struct drm_head *head, drmModeObjectPropertiesPtr props)
+{
+       struct drm_property_info *orientation =
+               &head->props_conn[WDRM_CONNECTOR_PANEL_ORIENTATION];
+       uint64_t kms_val =
+               drm_property_get_value(orientation, props,
+                                      WDRM_PANEL_ORIENTATION_NORMAL);
+
+       switch (kms_val) {
+       case WDRM_PANEL_ORIENTATION_NORMAL:
+               return WL_OUTPUT_TRANSFORM_NORMAL;
+       case WDRM_PANEL_ORIENTATION_UPSIDE_DOWN:
+               return WL_OUTPUT_TRANSFORM_180;
+       case WDRM_PANEL_ORIENTATION_LEFT_SIDE_UP:
+               return WL_OUTPUT_TRANSFORM_90;
+       case WDRM_PANEL_ORIENTATION_RIGHT_SIDE_UP:
+               return WL_OUTPUT_TRANSFORM_270;
+       default:
+               assert(!"unknown property value in get_panel_orientation");
+       }
+}
+
 static int
 parse_modeline(const char *s, drmModeModeInfo *mode)
 {
@@ -500,6 +523,9 @@ update_head_from_connector(struct drm_head *head,
        weston_head_set_physical_size(&head->base, head->connector->mmWidth,
                                      head->connector->mmHeight);
 
+       weston_head_set_transform(&head->base,
+                                 get_panel_orientation(head, props));
+
        /* Unknown connection status is assumed disconnected. */
        weston_head_set_connection_status(&head->base,
                        head->connector->connection == DRM_MODE_CONNECTED);