drm: Add Content protection type property
authorRamalingam C <ramalingam.c@intel.com>
Thu, 1 Aug 2019 11:41:14 +0000 (17:11 +0530)
committerRamalingam C <ramalingam.c@intel.com>
Tue, 6 Aug 2019 07:44:07 +0000 (13:14 +0530)
This patch adds a DRM ENUM property to the selected connectors.
This property is used for mentioning the protected content's type
from userspace to kernel HDCP authentication.

Type of the stream is decided by the protected content providers.
Type 0 content can be rendered on any HDCP protected display wires.
But Type 1 content can be rendered only on HDCP2.2 protected paths.

So when a userspace sets this property to Type 1 and starts the HDCP
enable, kernel will honour it only if HDCP2.2 authentication is through
for type 1. Else HDCP enable will be failed.

Pekka have completed the Weston DRM-backend review in
https://gitlab.freedesktop.org/wayland/weston/merge_requests/48
and the UAPI for HDCP 2.2 looks good.

The userspace is accepted in Weston.

v2:
  cp_content_type is replaced with content_protection_type [daniel]
  check at atomic_set_property is removed [Maarten]
v3:
  %s/content_protection_type/hdcp_content_type [Pekka]
v4:
  property is created for the first requested connector and then reused.
[Danvet]
v5:
  kernel doc nits addressed [Daniel]
  Rebased as part of patch reordering.
v6:
  Kernel docs are modified [pekka]
v7:
  More details in Kernel docs. [pekka]
v8:
  Few more clarification into kernel doc of content type [pekka]
v9:
  Small fixes in coding style.
v10:
  Moving DRM_MODE_HDCP_CONTENT_TYPEx definition to drm_hdcp.h [pekka]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: Pekka Paalanen <pekka.paalanen@collabora.com>
Acked-by: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/320957/?series=57232&rev=14
drivers/gpu/drm/drm_atomic_uapi.c
drivers/gpu/drm/drm_connector.c
drivers/gpu/drm/drm_hdcp.c
drivers/gpu/drm/i915/display/intel_hdcp.c
include/drm/drm_connector.h
include/drm/drm_hdcp.h
include/drm/drm_mode_config.h

index abe38bdf85ae6872ef31a0cb76c8ded6cd774b3b..19ae119f1a5daba4c33a5881309e8ac103c53e56 100644 (file)
@@ -747,6 +747,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
                        return -EINVAL;
                }
                state->content_protection = val;
                        return -EINVAL;
                }
                state->content_protection = val;
+       } else if (property == config->hdcp_content_type_property) {
+               state->hdcp_content_type = val;
        } else if (property == connector->colorspace_property) {
                state->colorspace = val;
        } else if (property == config->writeback_fb_id_property) {
        } else if (property == connector->colorspace_property) {
                state->colorspace = val;
        } else if (property == config->writeback_fb_id_property) {
@@ -831,6 +833,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
                        state->hdr_output_metadata->base.id : 0;
        } else if (property == config->content_protection_property) {
                *val = state->content_protection;
                        state->hdr_output_metadata->base.id : 0;
        } else if (property == config->content_protection_property) {
                *val = state->content_protection;
+       } else if (property == config->hdcp_content_type_property) {
+               *val = state->hdcp_content_type;
        } else if (property == config->writeback_fb_id_property) {
                /* Writeback framebuffer is one-shot, write and forget */
                *val = 0;
        } else if (property == config->writeback_fb_id_property) {
                /* Writeback framebuffer is one-shot, write and forget */
                *val = 0;
index d49e19f3de3ad2560b6a75a96ffc72b096940f00..cddb97f754154abf6651bc5d7ab2052e4f98cd3f 100644 (file)
@@ -988,6 +988,57 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
  *       is no longer protected and userspace should take appropriate action
  *       (whatever that might be).
  *
  *       is no longer protected and userspace should take appropriate action
  *       (whatever that might be).
  *
+ * HDCP Content Type:
+ *     This Enum property is used by the userspace to declare the content type
+ *     of the display stream, to kernel. Here display stream stands for any
+ *     display content that userspace intended to display through HDCP
+ *     encryption.
+ *
+ *     Content Type of a stream is decided by the owner of the stream, as
+ *     "HDCP Type0" or "HDCP Type1".
+ *
+ *     The value of the property can be one of the below:
+ *       - "HDCP Type0": DRM_MODE_HDCP_CONTENT_TYPE0 = 0
+ *       - "HDCP Type1": DRM_MODE_HDCP_CONTENT_TYPE1 = 1
+ *
+ *     When kernel starts the HDCP authentication (see "Content Protection"
+ *     for details), it uses the content type in "HDCP Content Type"
+ *     for performing the HDCP authentication with the display sink.
+ *
+ *     Please note in HDCP spec versions, a link can be authenticated with
+ *     HDCP 2.2 for Content Type 0/Content Type 1. Where as a link can be
+ *     authenticated with HDCP1.4 only for Content Type 0(though it is implicit
+ *     in nature. As there is no reference for Content Type in HDCP1.4).
+ *
+ *     HDCP2.2 authentication protocol itself takes the "Content Type" as a
+ *     parameter, which is a input for the DP HDCP2.2 encryption algo.
+ *
+ *     In case of Type 0 content protection request, kernel driver can choose
+ *     either of HDCP spec versions 1.4 and 2.2. When HDCP2.2 is used for
+ *     "HDCP Type 0", a HDCP 2.2 capable repeater in the downstream can send
+ *     that content to a HDCP 1.4 authenticated HDCP sink (Type0 link).
+ *     But if the content is classified as "HDCP Type 1", above mentioned
+ *     HDCP 2.2 repeater wont send the content to the HDCP sink as it can't
+ *     authenticate the HDCP1.4 capable sink for "HDCP Type 1".
+ *
+ *     Please note userspace can be ignorant of the HDCP versions used by the
+ *     kernel driver to achieve the "HDCP Content Type".
+ *
+ *     At current scenario, classifying a content as Type 1 ensures that the
+ *     content will be displayed only through the HDCP2.2 encrypted link.
+ *
+ *     Note that the HDCP Content Type property is introduced at HDCP 2.2, and
+ *     defaults to type 0. It is only exposed by drivers supporting HDCP 2.2
+ *     (hence supporting Type 0 and Type 1). Based on how next versions of
+ *     HDCP specs are defined content Type could be used for higher versions
+ *     too.
+ *
+ *     If content type is changed when "Content Protection" is not UNDESIRED,
+ *     then kernel will disable the HDCP and re-enable with new type in the
+ *     same atomic commit. And when "Content Protection" is ENABLED, it means
+ *     that link is HDCP authenticated and encrypted, for the transmission of
+ *     the Type of stream mentioned at "HDCP Content Type".
+ *
  * HDR_OUTPUT_METADATA:
  *     Connector property to enable userspace to send HDR Metadata to
  *     driver. This metadata is based on the composition and blending
  * HDR_OUTPUT_METADATA:
  *     Connector property to enable userspace to send HDR Metadata to
  *     driver. This metadata is based on the composition and blending
index cd837bd409f730483519728d54517079663b298b..ce235fd1c84447aad2058b628928954167efd188 100644 (file)
@@ -344,23 +344,41 @@ static struct drm_prop_enum_list drm_cp_enum_list[] = {
 };
 DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
 
 };
 DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
 
+static struct drm_prop_enum_list drm_hdcp_content_type_enum_list[] = {
+       { DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
+       { DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
+                drm_hdcp_content_type_enum_list)
+
 /**
  * drm_connector_attach_content_protection_property - attach content protection
  * property
  *
  * @connector: connector to attach CP property on.
 /**
  * drm_connector_attach_content_protection_property - attach content protection
  * property
  *
  * @connector: connector to attach CP property on.
+ * @hdcp_content_type: is HDCP Content Type property needed for connector
  *
  * This is used to add support for content protection on select connectors.
  * Content Protection is intentionally vague to allow for different underlying
  * technologies, however it is most implemented by HDCP.
  *
  *
  * This is used to add support for content protection on select connectors.
  * Content Protection is intentionally vague to allow for different underlying
  * technologies, however it is most implemented by HDCP.
  *
+ * When hdcp_content_type is true enum property called HDCP Content Type is
+ * created (if it is not already) and attached to the connector.
+ *
+ * This property is used for sending the protected content's stream type
+ * from userspace to kernel on selected connectors. Protected content provider
+ * will decide their type of their content and declare the same to kernel.
+ *
+ * Content type will be used during the HDCP 2.2 authentication.
+ * Content type will be set to &drm_connector_state.hdcp_content_type.
+ *
  * The content protection will be set to &drm_connector_state.content_protection
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
 int drm_connector_attach_content_protection_property(
  * The content protection will be set to &drm_connector_state.content_protection
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
 int drm_connector_attach_content_protection_property(
-               struct drm_connector *connector)
+               struct drm_connector *connector, bool hdcp_content_type)
 {
        struct drm_device *dev = connector->dev;
        struct drm_property *prop =
 {
        struct drm_device *dev = connector->dev;
        struct drm_property *prop =
@@ -377,6 +395,22 @@ int drm_connector_attach_content_protection_property(
                                   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
        dev->mode_config.content_protection_property = prop;
 
                                   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
        dev->mode_config.content_protection_property = prop;
 
+       if (!hdcp_content_type)
+               return 0;
+
+       prop = dev->mode_config.hdcp_content_type_property;
+       if (!prop)
+               prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+                                       drm_hdcp_content_type_enum_list,
+                                       ARRAY_SIZE(
+                                       drm_hdcp_content_type_enum_list));
+       if (!prop)
+               return -ENOMEM;
+
+       drm_object_attach_property(&connector->base, prop,
+                                  DRM_MODE_HDCP_CONTENT_TYPE0);
+       dev->mode_config.hdcp_content_type_property = prop;
+
        return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
        return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
index bc3a94d491c4d0992b24346d011840318ade13d2..2a4d10952b7423a4e175da6eb2b5df76f09e7f5c 100644 (file)
@@ -1829,7 +1829,9 @@ int intel_hdcp_init(struct intel_connector *connector,
        if (!shim)
                return -EINVAL;
 
        if (!shim)
                return -EINVAL;
 
-       ret = drm_connector_attach_content_protection_property(&connector->base);
+       ret =
+       drm_connector_attach_content_protection_property(&connector->base,
+                                                        false);
        if (ret)
                return ret;
 
        if (ret)
                return ret;
 
index fc5d08438333397feffce4bd4ddbf6afc1863172..0b9997e276890ceeeb9b4e6c3a19633ee6a8df1d 100644 (file)
@@ -602,6 +602,12 @@ struct drm_connector_state {
         */
        unsigned int content_type;
 
         */
        unsigned int content_type;
 
+       /**
+        * @hdcp_content_type: Connector property to pass the type of
+        * protected content. This is most commonly used for HDCP.
+        */
+       unsigned int hdcp_content_type;
+
        /**
         * @scaling_mode: Connector property to control the
         * upscaling, mostly used for built-in panels.
        /**
         * @scaling_mode: Connector property to control the
         * upscaling, mostly used for built-in panels.
@@ -1502,6 +1508,7 @@ const char *drm_get_dvi_i_select_name(int val);
 const char *drm_get_tv_subconnector_name(int val);
 const char *drm_get_tv_select_name(int val);
 const char *drm_get_content_protection_name(int val);
 const char *drm_get_tv_subconnector_name(int val);
 const char *drm_get_tv_select_name(int val);
 const char *drm_get_content_protection_name(int val);
+const char *drm_get_hdcp_content_type_name(int val);
 
 int drm_mode_create_dvi_i_properties(struct drm_device *dev);
 int drm_mode_create_tv_margin_properties(struct drm_device *dev);
 
 int drm_mode_create_dvi_i_properties(struct drm_device *dev);
 int drm_mode_create_tv_margin_properties(struct drm_device *dev);
index 13771a496e2b7d9c0abee98524ca2b4e23a8addf..82447af98aa26390989f752202c6f901cb98d961 100644 (file)
@@ -291,5 +291,10 @@ struct drm_connector;
 bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
                                 u8 *ksvs, u32 ksv_count);
 int drm_connector_attach_content_protection_property(
 bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
                                 u8 *ksvs, u32 ksv_count);
 int drm_connector_attach_content_protection_property(
-               struct drm_connector *connector);
+               struct drm_connector *connector, bool hdcp_content_type);
+
+/* Content Type classification for HDCP2.2 vs others */
+#define DRM_MODE_HDCP_CONTENT_TYPE0            0
+#define DRM_MODE_HDCP_CONTENT_TYPE1            1
+
 #endif
 #endif
index f57eea0481e0fd18a79d0c1178108619ae5e0a38..3bcbe30339f044cd18d7bef994b8d98271ca9eca 100644 (file)
@@ -849,6 +849,12 @@ struct drm_mode_config {
         */
        struct drm_property *content_protection_property;
 
         */
        struct drm_property *content_protection_property;
 
+       /**
+        * @hdcp_content_type_property: DRM ENUM property for type of
+        * Protected Content.
+        */
+       struct drm_property *hdcp_content_type_property;
+
        /* dumb ioctl parameters */
        uint32_t preferred_depth, prefer_shadow;
 
        /* dumb ioctl parameters */
        uint32_t preferred_depth, prefer_shadow;