Commit 7672dbba authored by Ramalingam C's avatar Ramalingam C

drm: Add Content protection type property

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: default avatarRamalingam C <ramalingam.c@intel.com>
Reviewed-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Acked-by: default avatarPekka Paalanen <pekka.paalanen@collabora.com>
Acked-by: default avatarJani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/320957/?series=57232&rev=14
parent c1233578
...@@ -747,6 +747,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, ...@@ -747,6 +747,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
return -EINVAL; return -EINVAL;
} }
state->content_protection = val; state->content_protection = val;
} else if (property == config->hdcp_content_type_property) {
state->hdcp_content_type = val;
} else if (property == connector->colorspace_property) { } else if (property == connector->colorspace_property) {
state->colorspace = val; state->colorspace = val;
} else if (property == config->writeback_fb_id_property) { } else if (property == config->writeback_fb_id_property) {
...@@ -831,6 +833,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector, ...@@ -831,6 +833,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
state->hdr_output_metadata->base.id : 0; state->hdr_output_metadata->base.id : 0;
} else if (property == config->content_protection_property) { } else if (property == config->content_protection_property) {
*val = state->content_protection; *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) { } else if (property == config->writeback_fb_id_property) {
/* Writeback framebuffer is one-shot, write and forget */ /* Writeback framebuffer is one-shot, write and forget */
*val = 0; *val = 0;
......
...@@ -988,6 +988,57 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = { ...@@ -988,6 +988,57 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
* is no longer protected and userspace should take appropriate action * is no longer protected and userspace should take appropriate action
* (whatever that might be). * (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: * HDR_OUTPUT_METADATA:
* Connector property to enable userspace to send HDR Metadata to * Connector property to enable userspace to send HDR Metadata to
* driver. This metadata is based on the composition and blending * driver. This metadata is based on the composition and blending
......
...@@ -344,23 +344,41 @@ static struct drm_prop_enum_list drm_cp_enum_list[] = { ...@@ -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 * drm_connector_attach_content_protection_property - attach content protection
* property * property
* *
* @connector: connector to attach CP property on. * @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. * This is used to add support for content protection on select connectors.
* Content Protection is intentionally vague to allow for different underlying * Content Protection is intentionally vague to allow for different underlying
* technologies, however it is most implemented by HDCP. * 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 * The content protection will be set to &drm_connector_state.content_protection
* *
* Returns: * Returns:
* Zero on success, negative errno on failure. * Zero on success, negative errno on failure.
*/ */
int drm_connector_attach_content_protection_property( 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_device *dev = connector->dev;
struct drm_property *prop = struct drm_property *prop =
...@@ -377,6 +395,22 @@ int drm_connector_attach_content_protection_property( ...@@ -377,6 +395,22 @@ int drm_connector_attach_content_protection_property(
DRM_MODE_CONTENT_PROTECTION_UNDESIRED); DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
dev->mode_config.content_protection_property = prop; 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; return 0;
} }
EXPORT_SYMBOL(drm_connector_attach_content_protection_property); EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
...@@ -1829,7 +1829,9 @@ int intel_hdcp_init(struct intel_connector *connector, ...@@ -1829,7 +1829,9 @@ int intel_hdcp_init(struct intel_connector *connector,
if (!shim) if (!shim)
return -EINVAL; return -EINVAL;
ret = drm_connector_attach_content_protection_property(&connector->base); ret =
drm_connector_attach_content_protection_property(&connector->base,
false);
if (ret) if (ret)
return ret; return ret;
......
...@@ -602,6 +602,12 @@ struct drm_connector_state { ...@@ -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 * @scaling_mode: Connector property to control the
* upscaling, mostly used for built-in panels. * upscaling, mostly used for built-in panels.
...@@ -1502,6 +1508,7 @@ const char *drm_get_dvi_i_select_name(int val); ...@@ -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_subconnector_name(int val);
const char *drm_get_tv_select_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_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_dvi_i_properties(struct drm_device *dev);
int drm_mode_create_tv_margin_properties(struct drm_device *dev); int drm_mode_create_tv_margin_properties(struct drm_device *dev);
......
...@@ -291,5 +291,10 @@ struct drm_connector; ...@@ -291,5 +291,10 @@ struct drm_connector;
bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev, bool drm_hdcp_check_ksvs_revoked(struct drm_device *dev,
u8 *ksvs, u32 ksv_count); u8 *ksvs, u32 ksv_count);
int drm_connector_attach_content_protection_property( 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
...@@ -849,6 +849,12 @@ struct drm_mode_config { ...@@ -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 */ /* dumb ioctl parameters */
uint32_t preferred_depth, prefer_shadow; uint32_t preferred_depth, prefer_shadow;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment