drm: content-type property for HDMI connector
authorStanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Tue, 15 May 2018 13:59:27 +0000 (16:59 +0300)
committerVille Syrjälä <ville.syrjala@linux.intel.com>
Thu, 17 May 2018 15:58:35 +0000 (18:58 +0300)
Added content_type property to drm_connector_state
in order to properly handle external HDMI TV content-type setting.

v2:
 * Moved helper function which attaches content type property
   to the drm core, as was suggested.
   Removed redundant connector state initialization.

v3:
 * Removed caps in drm_content_type_enum_list.
   After some discussion it turned out that HDMI Spec 1.4
   was wrongly assuming that IT Content(itc) bit doesn't affect
   Content type states, however itc bit needs to be manupulated
   as well. In order to not expose additional property for itc,
   for sake of simplicity it was decided to bind those together
   in same "content type" property.

v4:
 * Added it_content checking in intel_digital_connector_atomic_check.
   Fixed documentation for new content type enum.

v5:
 * Moved patch revision's description to commit messages.

v6:
 * Minor naming fix for the content type enumeration string.

v7:
 * Fix parameter name for documentation and parameter alignment
   in order not to get warning. Added Content Type description to
   new HDMI connector properties section.

v8:
 * Thrown away unneeded numbers from HDMI content-type property
   description. Switch to strings desription instead of plain
   definitions.

v9:
 * Moved away hdmi specific content-type enum from
   drm_connector_state. Content type property should probably not
   be bound to any specific connector interface in
   drm_connector_state.
   Same probably should be done to hdmi_picture_aspect_ration enum
   which is also contained in drm_connector_state. Added special
   helper function to get derive hdmi specific relevant infoframe
   fields.

v10:
 * Added usage description to HDMI properties kernel doc.

v11:
 * Created centralized function for filling HDMI AVI infoframe, based
   on correspondent DRM property value.

Acked-by: Hans Verkuil <hans.verkuil@cisco.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Stanislav Lisovskiy <stanislav.lisovskiy@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20180515135928.31092-2-stanislav.lisovskiy@intel.com
[vsyrjala: clean up checkpatch multiple blank lines warnings]
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Documentation/gpu/drm-kms.rst
Documentation/gpu/kms-properties.csv
drivers/gpu/drm/drm_atomic.c
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/drm_edid.c
include/drm/drm_connector.h
include/drm/drm_mode_config.h
include/uapi/drm/drm_mode.h

index 1dffd1ac4cd44be310fa7b8855c265cc57cd30ae..e233c2626bd01532a47a28e3dd6303873e2cf842 100644 (file)
@@ -517,6 +517,12 @@ Standard Connector Properties
 .. kernel-doc:: drivers/gpu/drm/drm_connector.c
    :doc: standard connector properties
 
+HDMI Specific Connector Properties
+-----------------------------
+
+.. kernel-doc:: drivers/gpu/drm/drm_connector.c
+   :doc: HDMI connector properties
+
 Plane Composition Properties
 ----------------------------
 
index 07ed22ea3bd670f3acd2d016963c6d1c5426997d..bfde04eddd148b8f669c3d2b633e52b08f2dd3e2 100644 (file)
@@ -17,6 +17,7 @@ Owner Module/Drivers,Group,Property Name,Type,Property Values,Object attached,De
 ,Virtual GPU,“suggested X”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an X offset for a connector
 ,,“suggested Y”,RANGE,"Min=0, Max=0xffffffff",Connector,property to suggest an Y offset for a connector
 ,Optional,"""aspect ratio""",ENUM,"{ ""None"", ""4:3"", ""16:9"" }",Connector,TDB
+,Optional,"""content type""",ENUM,"{ ""No Data"", ""Graphics"", ""Photo"", ""Cinema"", ""Game"" }",Connector,TBD
 i915,Generic,"""Broadcast RGB""",ENUM,"{ ""Automatic"", ""Full"", ""Limited 16:235"" }",Connector,"When this property is set to Limited 16:235 and CTM is set, the hardware will be programmed with the result of the multiplication of CTM by the limited range matrix to ensure the pixels normaly in the range 0..1.0 are remapped to the range 16/255..235/255."
 ,,“audio”,ENUM,"{ ""force-dvi"", ""off"", ""auto"", ""on"" }",Connector,TBD
 ,SDVO-TV,“mode”,ENUM,"{ ""NTSC_M"", ""NTSC_J"", ""NTSC_443"", ""PAL_B"" } etc.",Connector,TBD
index dc850b4b6e21965cd793be0749e300f9b7166974..07fef42869aa20702470e78027605b2d5f619593 100644 (file)
@@ -1270,6 +1270,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
                        state->link_status = val;
        } else if (property == config->aspect_ratio_property) {
                state->picture_aspect_ratio = val;
+       } else if (property == config->content_type_property) {
+               state->content_type = val;
        } else if (property == connector->scaling_mode_property) {
                state->scaling_mode = val;
        } else if (property == connector->content_protection_property) {
@@ -1355,6 +1357,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
                *val = state->link_status;
        } else if (property == config->aspect_ratio_property) {
                *val = state->picture_aspect_ratio;
+       } else if (property == config->content_type_property) {
+               *val = state->content_type;
        } else if (property == connector->scaling_mode_property) {
                *val = state->scaling_mode;
        } else if (property == connector->content_protection_property) {
index 9b9ba5d5ec0cb30549e678346161d9f21dc01a78..002b244391f9f88fea10be754ac7b76108bfee0a 100644 (file)
@@ -720,6 +720,14 @@ static const struct drm_prop_enum_list drm_aspect_ratio_enum_list[] = {
        { DRM_MODE_PICTURE_ASPECT_16_9, "16:9" },
 };
 
+static const struct drm_prop_enum_list drm_content_type_enum_list[] = {
+       { DRM_MODE_CONTENT_TYPE_NO_DATA, "No Data" },
+       { DRM_MODE_CONTENT_TYPE_GRAPHICS, "Graphics" },
+       { DRM_MODE_CONTENT_TYPE_PHOTO, "Photo" },
+       { DRM_MODE_CONTENT_TYPE_CINEMA, "Cinema" },
+       { DRM_MODE_CONTENT_TYPE_GAME, "Game" },
+};
+
 static const struct drm_prop_enum_list drm_panel_orientation_enum_list[] = {
        { DRM_MODE_PANEL_ORIENTATION_NORMAL,    "Normal"        },
        { DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP, "Upside Down"   },
@@ -996,6 +1004,84 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
 
+/**
+ * DOC: HDMI connector properties
+ *
+ * content type (HDMI specific):
+ *     Indicates content type setting to be used in HDMI infoframes to indicate
+ *     content type for the external device, so that it adjusts it's display
+ *     settings accordingly.
+ *
+ *     The value of this property can be one of the following:
+ *
+ *     No Data:
+ *             Content type is unknown
+ *     Graphics:
+ *             Content type is graphics
+ *     Photo:
+ *             Content type is photo
+ *     Cinema:
+ *             Content type is cinema
+ *     Game:
+ *             Content type is game
+ *
+ *     Drivers can set up this property by calling
+ *     drm_connector_attach_content_type_property(). Decoding to
+ *     infoframe values is done through
+ *     drm_hdmi_get_content_type_from_property() and
+ *     drm_hdmi_get_itc_bit_from_property().
+ */
+
+/**
+ * drm_connector_attach_content_type_property - attach content-type property
+ * @connector: connector to attach content type property on.
+ *
+ * Called by a driver the first time a HDMI connector is made.
+ */
+int drm_connector_attach_content_type_property(struct drm_connector *connector)
+{
+       if (!drm_mode_create_content_type_property(connector->dev))
+               drm_object_attach_property(&connector->base,
+                                          connector->dev->mode_config.content_type_property,
+                                          DRM_MODE_CONTENT_TYPE_NO_DATA);
+       return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_content_type_property);
+
+
+/**
+ * drm_hdmi_avi_infoframe_content_type() - fill the HDMI AVI infoframe
+ *                                         content type information, based
+ *                                         on correspondent DRM property.
+ * @frame: HDMI AVI infoframe
+ * @conn_state: DRM display connector state
+ *
+ */
+void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
+                                        const struct drm_connector_state *conn_state)
+{
+       switch (conn_state->content_type) {
+       case DRM_MODE_CONTENT_TYPE_GRAPHICS:
+               frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
+               break;
+       case DRM_MODE_CONTENT_TYPE_CINEMA:
+               frame->content_type = HDMI_CONTENT_TYPE_CINEMA;
+               break;
+       case DRM_MODE_CONTENT_TYPE_GAME:
+               frame->content_type = HDMI_CONTENT_TYPE_GAME;
+               break;
+       case DRM_MODE_CONTENT_TYPE_PHOTO:
+               frame->content_type = HDMI_CONTENT_TYPE_PHOTO;
+               break;
+       default:
+               /* Graphics is the default(0) */
+               frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
+       }
+
+       frame->itc = conn_state->content_type != DRM_MODE_CONTENT_TYPE_NO_DATA;
+}
+EXPORT_SYMBOL(drm_hdmi_avi_infoframe_content_type);
+
 /**
  * drm_create_tv_properties - create TV specific connector properties
  * @dev: DRM device
@@ -1260,6 +1346,33 @@ int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_create_aspect_ratio_property);
 
+/**
+ * drm_mode_create_content_type_property - create content type property
+ * @dev: DRM device
+ *
+ * Called by a driver the first time it's needed, must be attached to desired
+ * connectors.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_mode_create_content_type_property(struct drm_device *dev)
+{
+       if (dev->mode_config.content_type_property)
+               return 0;
+
+       dev->mode_config.content_type_property =
+               drm_property_create_enum(dev, 0, "content type",
+                                        drm_content_type_enum_list,
+                                        ARRAY_SIZE(drm_content_type_enum_list));
+
+       if (dev->mode_config.content_type_property == NULL)
+               return -ENOMEM;
+
+       return 0;
+}
+EXPORT_SYMBOL(drm_mode_create_content_type_property);
+
 /**
  * drm_mode_create_suggested_offset_properties - create suggests offset properties
  * @dev: DRM device
index 40e1e24f2ff0847d3d9fd65bd2069b28ab9b2c2a..82f1ab09169dae490caf9dc868cf65498101f730 100644 (file)
@@ -4872,6 +4872,14 @@ drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame,
 
        frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE;
 
+       /*
+        * As some drivers don't support atomic, we can't use connector state.
+        * So just initialize the frame with default values, just the same way
+        * as it's done with other properties here.
+        */
+       frame->content_type = HDMI_CONTENT_TYPE_GRAPHICS;
+       frame->itc = 0;
+
        /*
         * Populate picture aspect ratio from either
         * user input (if specified) or from the CEA mode list.
index 675cc3f8cf85292ce19aadee37d32f1f143771d8..ee4c48218c85bc3b5cfde66fca913e90440b7bb2 100644 (file)
@@ -418,6 +418,14 @@ struct drm_connector_state {
         */
        enum hdmi_picture_aspect picture_aspect_ratio;
 
+       /**
+        * @content_type: Connector property to control the
+        * HDMI infoframe content type setting.
+        * The %DRM_MODE_CONTENT_TYPE_\* values much
+        * match the values.
+        */
+       unsigned int content_type;
+
        /**
         * @scaling_mode: Connector property to control the
         * upscaling, mostly used for built-in panels.
@@ -1089,11 +1097,16 @@ int drm_mode_create_tv_properties(struct drm_device *dev,
                                  unsigned int num_modes,
                                  const char * const modes[]);
 int drm_mode_create_scaling_mode_property(struct drm_device *dev);
+int drm_connector_attach_content_type_property(struct drm_connector *dev);
 int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
                                               u32 scaling_mode_mask);
 int drm_connector_attach_content_protection_property(
                struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
+int drm_mode_create_content_type_property(struct drm_device *dev);
+void drm_hdmi_avi_infoframe_content_type(struct hdmi_avi_infoframe *frame,
+                                        const struct drm_connector_state *conn_state);
+
 int drm_mode_create_suggested_offset_properties(struct drm_device *dev);
 
 int drm_mode_connector_set_path_property(struct drm_connector *connector,
index 33b3a96d66d0a4de3dcb0910edb75fa310eb7a4d..fb45839179dd44247dce5658c2ef015fa9deecde 100644 (file)
@@ -726,6 +726,11 @@ struct drm_mode_config {
         * HDMI infoframe aspect ratio setting.
         */
        struct drm_property *aspect_ratio_property;
+       /**
+        * @content_type_property: Optional connector property to control the
+        * HDMI infoframe content type setting.
+        */
+       struct drm_property *content_type_property;
        /**
         * @degamma_lut_property: Optional CRTC property to set the LUT used to
         * convert the framebuffer's colors to linear gamma.
index 4b3a1bb58e68053bd880aa373fe5385730baaade..971c016b368cd015ca149d81c25f74f1994f09ab 100644 (file)
@@ -96,6 +96,13 @@ extern "C" {
 #define DRM_MODE_PICTURE_ASPECT_64_27          3
 #define DRM_MODE_PICTURE_ASPECT_256_135                4
 
+/* Content type options */
+#define DRM_MODE_CONTENT_TYPE_NO_DATA          0
+#define DRM_MODE_CONTENT_TYPE_GRAPHICS         1
+#define DRM_MODE_CONTENT_TYPE_PHOTO            2
+#define DRM_MODE_CONTENT_TYPE_CINEMA           3
+#define DRM_MODE_CONTENT_TYPE_GAME             4
+
 /* Aspect ratio flag bitmask (4 bits 22:19) */
 #define DRM_MODE_FLAG_PIC_AR_MASK              (0x0F<<19)
 #define  DRM_MODE_FLAG_PIC_AR_NONE \