drm: add connector info/property for non-desktop displays [v2]
authorDave Airlie <airlied@redhat.com>
Mon, 16 Oct 2017 04:08:09 +0000 (05:08 +0100)
committerDave Airlie <airlied@redhat.com>
Thu, 23 Nov 2017 02:45:25 +0000 (12:45 +1000)
This adds the infrastructure needed to quirk displays
using edid and to mark them a non-desktop.

A non-desktop display is one which shouldn't normally be included
as a part of a desktop environment.

This is meant to cover head mounted devices like HTC Vive.

v2: Change description from non-standard to non-desktop, add docs

Reviewed-by: Keith Packard <keithp@keithp.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
fixup docs

drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/drm_edid.c
include/drm/drm_connector.h
include/drm/drm_mode_config.h

index 704fc893461629d71955e513f61c9e34c2f2a057..25f4b2e9a44fcdd5cef668df014001e1c1b1c90e 100644 (file)
@@ -234,6 +234,10 @@ int drm_connector_init(struct drm_device *dev,
                                   config->link_status_property,
                                   0);
 
+       drm_object_attach_property(&connector->base,
+                                  config->non_desktop_property,
+                                  0);
+
        if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
                drm_object_attach_property(&connector->base, config->prop_crtc_id, 0);
        }
@@ -763,6 +767,10 @@ DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
  *      value of link-status is "GOOD". If something fails during or after modeset,
  *      the kernel driver may set this to "BAD" and issue a hotplug uevent. Drivers
  *      should update this value using drm_mode_connector_set_link_status_property().
+ * non_desktop:
+ *     Indicates the output should be ignored for purposes of displaying a
+ *     standard desktop environment or console. This is most likely because
+ *     the output device is not rectilinear.
  *
  * Connectors also have one standardized atomic property:
  *
@@ -811,6 +819,11 @@ int drm_connector_create_standard_properties(struct drm_device *dev)
                return -ENOMEM;
        dev->mode_config.link_status_property = prop;
 
+       prop = drm_property_create_bool(dev, DRM_MODE_PROP_IMMUTABLE, "non-desktop");
+       if (!prop)
+               return -ENOMEM;
+       dev->mode_config.non_desktop_property = prop;
+
        return 0;
 }
 
@@ -1194,6 +1207,10 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,
        if (edid)
                size = EDID_LENGTH * (1 + edid->extensions);
 
+       drm_object_property_set_value(&connector->base,
+                                     dev->mode_config.non_desktop_property,
+                                     connector->display_info.non_desktop);
+
        ret = drm_property_replace_global_blob(dev,
                                               &connector->edid_blob_ptr,
                                               size,
index 00ddabfbf980401f8d58a4d46eff8ee60282ee5f..1e24d5d9d659732a6f64560fdfe25f66b1d03a9f 100644 (file)
@@ -82,6 +82,8 @@
 #define EDID_QUIRK_FORCE_6BPC                  (1 << 10)
 /* Force 10bpc */
 #define EDID_QUIRK_FORCE_10BPC                 (1 << 11)
+/* Non desktop display (i.e. HMD) */
+#define EDID_QUIRK_NON_DESKTOP                 (1 << 12)
 
 struct detailed_mode_closure {
        struct drm_connector *connector;
@@ -4393,7 +4395,7 @@ static void drm_parse_cea_ext(struct drm_connector *connector,
 }
 
 static void drm_add_display_info(struct drm_connector *connector,
-                                struct edid *edid)
+                                struct edid *edid, u32 quirks)
 {
        struct drm_display_info *info = &connector->display_info;
 
@@ -4407,6 +4409,8 @@ static void drm_add_display_info(struct drm_connector *connector,
        info->max_tmds_clock = 0;
        info->dvi_dual = false;
 
+       info->non_desktop = !!(quirks & EDID_QUIRK_NON_DESKTOP);
+
        if (edid->revision < 3)
                return;
 
@@ -4627,7 +4631,7 @@ int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
         * To avoid multiple parsing of same block, lets parse that map
         * from sink info, before parsing CEA modes.
         */
-       drm_add_display_info(connector, edid);
+       drm_add_display_info(connector, edid, quirks);
 
        /*
         * EDID spec says modes should be preferred in this order:
index 7a714054301226ffe34de6e22b43e38bd1979ea1..df9807a3caaea4d9f77e0797e594f3a8b12ddd11 100644 (file)
@@ -284,6 +284,11 @@ struct drm_display_info {
         * @hdmi: advance features of a HDMI sink.
         */
        struct drm_hdmi_info hdmi;
+
+       /**
+        * @non_desktop: Non desktop display (HMD).
+        */
+       bool non_desktop;
 };
 
 int drm_display_info_set_bus_formats(struct drm_display_info *info,
index 0b4ac2ebc6105a0f3d9f364c7bf83eeee2928ad4..b21e827c5c78775742533d28f3baebfd6e0a9b5e 100644 (file)
@@ -728,6 +728,13 @@ struct drm_mode_config {
         */
        struct drm_property *suggested_y_property;
 
+       /**
+        * @non_desktop_property: Optional connector property with a hint
+        * that device isn't a standard display, and the console/desktop,
+        * should not be displayed on it.
+        */
+       struct drm_property *non_desktop_property;
+
        /* dumb ioctl parameters */
        uint32_t preferred_depth, prefer_shadow;