dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] HDCP2.2 Phase II
@ 2019-02-26  7:35 Ramalingam C
  2019-02-26  7:36 ` [PATCH 01/10] drm: Add CP content type property Ramalingam C
                   ` (10 more replies)
  0 siblings, 11 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:35 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

HDCP2.2 phase-II mojorly adds below features:
	Addition of three connector properties
		CP_Content_Type
		CP_SRM
		CP_Downstream_Info
	parsing for HDCP1.4 and 2.2 SRM Blobs
	Once HDCP1.4/2.2 authentication is completed gathering the all
		downstream topology for userspace 
	Extending debugfs entry to provide the HDCP2.2 capability too.

CP_Content_Type:
	This property is used to indicate the content type
classification of a stream. Which indicate the HDCP version required
for the rendering of that streams. This conten type is one of the
parameter in the HDCP2.2 authentication flow, as even downstream
repeaters will mandate the HDCP version requirement.

Two values possible for content type of a stream:
	Type 0: Stream can be rendered only on HDCP encrypted link no
		restriction on HDCP versions.
	Type 1: Stream can be rendered only on HDCP2.2 encrypted link.

There is a parallel effort in #wayland community to add the support for
HDCP2.2 along with content type support. Patches are under review in
#wayland community.

CP_SRM:
This blob property is used by the userspace to pass the SRM table
of HDCP1.4 and 2.2. These are nothing but revocated list of receiver IDs
of the HDCP sinks. KMD will use this list to identify the revocated
devices in the HDCP authentication and deny the hdcp encryption to it.

Work in progress to add the SRM support in the weston HDCP stack.
Yet to publish the patches in the #wayland community.

CP_Downstream_Info:
This blob property is used by the kernel to pass the downstream topology
of the HDCP encrypted port to the userspace.

This is used by the userspace to implement the HDCP repeater, which KMD
implementing the HDCP transmitters(downstream ports) and userspace
implementing the upstream port(HDCP receiver).

Discussion is on going to add the downstream_info support in the
weston HDCP stack.

Test-with: 1551165805-19130-2-git-send-email-ramalingam.c@intel.com

Ramalingam C (10):
  drm: Add CP content type property
  drm/i915: Attach content type property
  drm: Add CP System Renewability Msg Property
  drm/i915: Add HDCP SRM Blob parsing
  drm/i915: Add revocation check on HDCP1.4 Ksvs
  drm/i915: SRM parsing and revocation check for HDCP2
  drm: Add CP downstream_info property
  drm/i915: Populate downstream info for HDCP1.4
  drm/i915: Populate downstream info for HDCP2.2
  drm/i915: debugfs: HDCP2.2 capability read

 drivers/gpu/drm/drm_atomic_uapi.c   |  23 +++
 drivers/gpu/drm/drm_connector.c     | 204 ++++++++++++++++++++
 drivers/gpu/drm/i915/i915_debugfs.c |  13 +-
 drivers/gpu/drm/i915/intel_ddi.c    |  23 ++-
 drivers/gpu/drm/i915/intel_drv.h    |  11 +-
 drivers/gpu/drm/i915/intel_hdcp.c   | 373 ++++++++++++++++++++++++++++++++++--
 include/drm/drm_connector.h         |  40 ++++
 include/drm/drm_hdcp.h              |  35 ++++
 include/uapi/drm/drm_mode.h         |  39 ++++
 9 files changed, 737 insertions(+), 24 deletions(-)

-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH 01/10] drm: Add CP content type property
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-03-05 14:39   ` [Intel-gfx] " Maarten Lankhorst
  2019-02-26  7:36 ` [PATCH 02/10] drm/i915: Attach " Ramalingam C
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

This patch adds a DRM ENUM property to the selected connectors.
This property is used for pass the protected content's type
from userspace to kernel HDCP authentication.

Type of the stream is decided by the protected content providers as
Type 0/1.

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 upon a content protection request with Type 1 as Content type from
userspace, Kernel will declare success only if the HDCP2.2
authentication is successful.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/drm_atomic_uapi.c | 10 ++++++
 drivers/gpu/drm/drm_connector.c   | 64 +++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h       | 15 +++++++++
 include/uapi/drm/drm_mode.h       |  4 +++
 4 files changed, 93 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 4eb81f10bc54..5289486565ce 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -746,6 +746,14 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 			return -EINVAL;
 		}
 		state->content_protection = val;
+	} else if (property == connector->cp_content_type_property) {
+		if (state->content_protection !=
+		    DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+		    state->cp_content_type != val) {
+			DRM_DEBUG_KMS("Disable CP, then change Type\n");
+			return -EINVAL;
+		}
+		state->cp_content_type = val;
 	} else if (property == connector->colorspace_property) {
 		state->colorspace = val;
 	} else if (property == config->writeback_fb_id_property) {
@@ -822,6 +830,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->scaling_mode;
 	} else if (property == connector->content_protection_property) {
 		*val = state->content_protection;
+	} else if (property == connector->cp_content_type_property) {
+		*val = state->cp_content_type;
 	} else if (property == config->writeback_fb_id_property) {
 		/* Writeback framebuffer is one-shot, write and forget */
 		*val = 0;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 07d65a16c623..5d7738e1e977 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -853,6 +853,13 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
 	{ DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER, "DCI-P3_RGB_Theater" },
 };
 
+static struct drm_prop_enum_list drm_cp_content_type_enum_list[] = {
+	{ DRM_MODE_CP_CONTENT_TYPE0, "Type 0" },
+	{ DRM_MODE_CP_CONTENT_TYPE1, "Type 1" },
+};
+
+DRM_ENUM_NAME_FN(drm_get_cp_content_type_name, drm_cp_content_type_enum_list)
+
 /**
  * DOC: standard connector properties
  *
@@ -958,6 +965,25 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
  *	  the value transitions from ENABLED to DESIRED. This signifies the link
  *	  is no longer protected and userspace should take appropriate action
  *	  (whatever that might be).
+ * CP_Content_Type:
+ *	This property is used by the userspace to configure the kernel with
+ *	upcoming stream's content type. Content Type of a stream is decided by
+ *	the owner of the stream, as Type 0 or Type 1.
+ *
+ *	The value of the property can be one the below:
+ *	  - DRM_MODE_CP_CONTENT_TYPE0 = 0
+ *		Type 0 streams can be transmitted on a link which is encrypted
+ *		with HDCP 1.4 or HDCP 2.2.
+ *	  - DRM_MODE_CP_CONTENT_TYPE1 = 1
+ *		Type 1 streams can be transmitted on a link which is encrypted
+ *		only with HDCP2.2.
+ *
+ *	Please note this content type is introduced at HDCP2.2 and used in its
+ *	authentication process.
+ *
+ *	Guideline for programming:
+ *	  - Property state can be changed only when "Content Protection state is
+ *		DRM_MODE_CONTENT_PROTECTION_UNDESIRED.
  *
  * max bpc:
  *	This range property is used by userspace to limit the bit depth. When
@@ -1548,6 +1574,44 @@ int drm_connector_attach_content_protection_property(
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
 
 /**
+ * drm_connector_attach_cp_content_type_property - attach cp content type
+ * property
+ *
+ * @connector: connector to attach cp content type property on.
+ *
+ * This is used to add support 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.
+ *
+ * This information will be used during the HDCP2.2 authentication.
+ *
+ * Content type will be set to &drm_connector_state.cp_content_type.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int
+drm_connector_attach_cp_content_type_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop;
+
+	prop = drm_property_create_enum(dev, 0, "CP_Content_Type",
+					drm_cp_content_type_enum_list,
+					ARRAY_SIZE(
+					drm_cp_content_type_enum_list));
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop,
+				   DRM_MODE_CP_CONTENT_TYPE0);
+	connector->cp_content_type_property = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_cp_content_type_property);
+
+/**
  * drm_mode_create_aspect_ratio_property - create aspect ratio property
  * @dev: DRM device
  *
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index c8061992d6cb..820feb7f0b42 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -519,6 +519,12 @@ struct drm_connector_state {
 	unsigned int content_type;
 
 	/**
+	 * @cp_content_type: Connector property to pass the type of protected
+	 * content. This is most commonly used for HDCP.
+	 */
+	unsigned int cp_content_type;
+
+	/**
 	 * @scaling_mode: Connector property to control the
 	 * upscaling, mostly used for built-in panels.
 	 */
@@ -1036,6 +1042,12 @@ struct drm_connector {
 	struct drm_property *colorspace_property;
 
 	/**
+	 * @cp_content_type_property: DRM ENUM property for type of
+	 * Protected Content.
+	 */
+	struct drm_property *cp_content_type_property;
+
+	/**
 	 * @path_blob_ptr:
 	 *
 	 * DRM blob property data for the DP MST path property. This should only
@@ -1294,6 +1306,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_cp_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);
@@ -1309,6 +1322,8 @@ int drm_connector_attach_vrr_capable_property(
 		struct drm_connector *connector);
 int drm_connector_attach_content_protection_property(
 		struct drm_connector *connector);
+int drm_connector_attach_cp_content_type_property(
+		struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_colorspace_property(struct drm_connector *connector);
 int drm_mode_create_content_type_property(struct drm_device *dev);
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index a439c2e67896..8504e3110e19 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -210,6 +210,10 @@ extern "C" {
 #define DRM_MODE_CONTENT_PROTECTION_DESIRED     1
 #define DRM_MODE_CONTENT_PROTECTION_ENABLED     2
 
+/* Content Type classification for HDCP2.2 vs others */
+#define DRM_MODE_CP_CONTENT_TYPE0		0
+#define DRM_MODE_CP_CONTENT_TYPE1		1
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 02/10] drm/i915: Attach content type property
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
  2019-02-26  7:36 ` [PATCH 01/10] drm: Add CP content type property Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-03-05 14:58   ` [Intel-gfx] " Maarten Lankhorst
  2019-02-26  7:36 ` [PATCH 03/10] drm: Add CP System Renewability Msg Property Ramalingam C
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

Attaches the content type property for HDCP2.2 capable connectors.

Implements the update of content type from property and apply the
restriction on HDCP version selection.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c  | 21 +++++++++++++++------
 drivers/gpu/drm/i915/intel_drv.h  |  2 +-
 drivers/gpu/drm/i915/intel_hdcp.c | 18 +++++++++++++++---
 3 files changed, 31 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 1355be8dec3b..ffe7759a3f3a 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3499,7 +3499,8 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
 	/* Enable hdcp if it's desired */
 	if (conn_state->content_protection ==
 	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
-		intel_hdcp_enable(to_intel_connector(conn_state->connector));
+		intel_hdcp_enable(to_intel_connector(conn_state->connector),
+				  (u8)conn_state->cp_content_type);
 }
 
 static void intel_disable_ddi_dp(struct intel_encoder *encoder,
@@ -3562,21 +3563,29 @@ static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder,
 	intel_panel_update_backlight(encoder, crtc_state, conn_state);
 }
 
-static void intel_ddi_update_pipe(struct intel_encoder *encoder,
+static void intel_ddi_update_hdcp(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
-	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
-		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
-
 	if (conn_state->content_protection ==
 	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
-		intel_hdcp_enable(to_intel_connector(conn_state->connector));
+		intel_hdcp_enable(to_intel_connector(conn_state->connector),
+				  (u8)conn_state->cp_content_type);
 	else if (conn_state->content_protection ==
 		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
 		intel_hdcp_disable(to_intel_connector(conn_state->connector));
 }
 
+static void intel_ddi_update_pipe(struct intel_encoder *encoder,
+				  const struct intel_crtc_state *crtc_state,
+				  const struct drm_connector_state *conn_state)
+{
+	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
+		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
+
+	intel_ddi_update_hdcp(encoder, crtc_state, conn_state);
+}
+
 static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
 					 const struct intel_crtc_state *pipe_config,
 					 enum port port)
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 81ec73e4a083..04cff672aead 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2151,7 +2151,7 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
 			     struct drm_connector_state *new_state);
 int intel_hdcp_init(struct intel_connector *connector,
 		    const struct intel_hdcp_shim *hdcp_shim);
-int intel_hdcp_enable(struct intel_connector *connector);
+int intel_hdcp_enable(struct intel_connector *connector, u8 content_type);
 int intel_hdcp_disable(struct intel_connector *connector);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
 bool intel_hdcp_capable(struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 9ce09f67776d..ab25264a74a4 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1782,6 +1782,12 @@ static void intel_hdcp2_init(struct intel_connector *connector)
 		return;
 	}
 
+	ret = drm_connector_attach_cp_content_type_property(&connector->base);
+	if (ret) {
+		kfree(hdcp->port_data.streams);
+		return;
+	}
+
 	hdcp->hdcp2_supported = true;
 }
 
@@ -1811,7 +1817,7 @@ int intel_hdcp_init(struct intel_connector *connector,
 	return 0;
 }
 
-int intel_hdcp_enable(struct intel_connector *connector)
+int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
@@ -1823,6 +1829,8 @@ int intel_hdcp_enable(struct intel_connector *connector)
 	mutex_lock(&hdcp->mutex);
 	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
 
+	hdcp->content_type = content_type;
+
 	/*
 	 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 	 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
@@ -1833,8 +1841,12 @@ int intel_hdcp_enable(struct intel_connector *connector)
 			check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS;
 	}
 
-	/* When HDCP2.2 fails, HDCP1.4 will be attempted */
-	if (ret && intel_hdcp_capable(connector)) {
+	/*
+	 * When HDCP2.2 fails and Content Type is not Type1, HDCP1.4 will
+	 * be attempted.
+	 */
+	if (ret && intel_hdcp_capable(connector) &&
+	    hdcp->content_type != DRM_MODE_CP_CONTENT_TYPE1) {
 		ret = _intel_hdcp_enable(connector);
 	}
 
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 03/10] drm: Add CP System Renewability Msg Property
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
  2019-02-26  7:36 ` [PATCH 01/10] drm: Add CP content type property Ramalingam C
  2019-02-26  7:36 ` [PATCH 02/10] drm/i915: Attach " Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-02-26  7:36 ` [PATCH 04/10] drm/i915: Add HDCP SRM Blob parsing Ramalingam C
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

This patch adds a drm blob property to the selected connector.
This property will be used to pass the SRM Blob ID from userspace
to kernel.

Revocated ksv list from SRM Table will be used by the kernel in the HDCP
authentication.

Kernel doesn't validate the incoming SRM table or store it in
non-volatile storage. So it is expected that userspace will provide the
latest valid SRM table on every power cycle before the HDCP
authentication starts.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/drm_atomic_uapi.c | 10 ++++++++
 drivers/gpu/drm/drm_connector.c   | 52 +++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h       | 13 ++++++++++
 3 files changed, 75 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 5289486565ce..9c57d8c07d09 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -754,6 +754,14 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 			return -EINVAL;
 		}
 		state->cp_content_type = val;
+	} else if (property == connector->cp_srm_property) {
+		if (state->content_protection !=
+		    DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
+		    state->cp_srm_blob_id != val) {
+			DRM_DEBUG_KMS("Disable CP, then change SRM Blob\n");
+			return -EINVAL;
+		}
+		state->cp_srm_blob_id = val;
 	} else if (property == connector->colorspace_property) {
 		state->colorspace = val;
 	} else if (property == config->writeback_fb_id_property) {
@@ -832,6 +840,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->content_protection;
 	} else if (property == connector->cp_content_type_property) {
 		*val = state->cp_content_type;
+	} else if (property == connector->cp_srm_property) {
+		*val = state->cp_srm_blob_id;
 	} else if (property == config->writeback_fb_id_property) {
 		/* Writeback framebuffer is one-shot, write and forget */
 		*val = 0;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 5d7738e1e977..510941ad532f 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -984,6 +984,24 @@ DRM_ENUM_NAME_FN(drm_get_cp_content_type_name, drm_cp_content_type_enum_list)
  *	Guideline for programming:
  *	  - Property state can be changed only when "Content Protection state is
  *		DRM_MODE_CONTENT_PROTECTION_UNDESIRED.
+ * CP_SRM:
+ *	This Blob property is used by the userspace to pass the revocated
+ *	receiver ID list of HDCP 1.4 and/or 2.2 versions.
+ *	In the HDCP authentication, Kernel uses this list to identify the HDCP
+ *	sink which are revocated by the DCP LLC.
+ *
+ *	Please note:
+ *	  - Userspace is expected to validate the integrity of the SRM table
+ *	    through the DCP signatures.
+ *	  - Userspace has to store the latest SRM securely in non-volatile
+ *	    storage.
+ *	  - Kernel doesn't store or validate the incoming SRM tables. So on
+ *	    every power cycle, before every HDCP authentication, userspace is
+ *	    expected to pass the latest valid SRM to kernel.
+ *
+ *	Guideline for programming:
+ *	  - Property state can be changed only when "Content Protection state is
+ *		DRM_MODE_CONTENT_PROTECTION_UNDESIRED.
  *
  * max bpc:
  *	This range property is used by userspace to limit the bit depth. When
@@ -1612,6 +1630,40 @@ drm_connector_attach_cp_content_type_property(struct drm_connector *connector)
 EXPORT_SYMBOL(drm_connector_attach_cp_content_type_property);
 
 /**
+ * drm_connector_attach_cp_srm_property - attach cp srm
+ * property
+ *
+ * @connector: connector to attach cp srm property on.
+ *
+ * This is used to add support for sending the SRM table from userspace to
+ * kernel on selected connectors. Protected content provider will provide
+ * the system renewability Message(SRM) to userspace before requesting for
+ * HDCP on a port. Hence if a Port supports content protection (mostly HDCP)
+ * then this property will be attached to receive the SRM for revocation check
+ * of the ksvs.
+ *
+ * The srm blob id will be set to &drm_connector_state.cp_srm_blob_id
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_cp_srm_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop;
+
+	prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, "CP_SRM", 0);
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop, 0);
+	connector->cp_srm_property = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_cp_srm_property);
+
+/**
  * drm_mode_create_aspect_ratio_property - create aspect ratio property
  * @dev: DRM device
  *
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 820feb7f0b42..796e5d5e9e5f 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -525,6 +525,12 @@ struct drm_connector_state {
 	unsigned int cp_content_type;
 
 	/**
+	 * @cp_srm_blob_id: Connector property to pass the SRM table for content
+	 * protection. This is most commonly used for HDCP.
+	 */
+	unsigned int cp_srm_blob_id;
+
+	/**
 	 * @scaling_mode: Connector property to control the
 	 * upscaling, mostly used for built-in panels.
 	 */
@@ -1048,6 +1054,12 @@ struct drm_connector {
 	struct drm_property *cp_content_type_property;
 
 	/**
+	 * @cp_srm_property: DRM BLOB property for content
+	 * protection SRM information.
+	 */
+	struct drm_property *cp_srm_property;
+
+	/**
 	 * @path_blob_ptr:
 	 *
 	 * DRM blob property data for the DP MST path property. This should only
@@ -1324,6 +1336,7 @@ int drm_connector_attach_content_protection_property(
 		struct drm_connector *connector);
 int drm_connector_attach_cp_content_type_property(
 		struct drm_connector *connector);
+int drm_connector_attach_cp_srm_property(struct drm_connector *connector);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_colorspace_property(struct drm_connector *connector);
 int drm_mode_create_content_type_property(struct drm_device *dev);
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 04/10] drm/i915: Add HDCP SRM Blob parsing
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
                   ` (2 preceding siblings ...)
  2019-02-26  7:36 ` [PATCH 03/10] drm: Add CP System Renewability Msg Property Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-02-26  7:36 ` [PATCH 05/10] drm/i915: Add revocation check on HDCP1.4 Ksvs Ramalingam C
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

This patch adds a drm blob property to selected connectors.
And also adds capability to parse the new HDCP1.4 srm blob passed
through cp_srm_property.

The revocated KSV list and their counts are stored in
the intel_hdcp. This list should be used for revocation check
of BKSVs in first stage HDCP authentication and for revocation check of
ksv_fifo in second stage authentication.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_ddi.c  |   6 +-
 drivers/gpu/drm/i915/intel_drv.h  |   8 ++-
 drivers/gpu/drm/i915/intel_hdcp.c | 147 +++++++++++++++++++++++++++++++++++++-
 include/drm/drm_hdcp.h            |  14 ++++
 4 files changed, 170 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index ffe7759a3f3a..1f935fe9c466 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3500,7 +3500,8 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
 	if (conn_state->content_protection ==
 	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
 		intel_hdcp_enable(to_intel_connector(conn_state->connector),
-				  (u8)conn_state->cp_content_type);
+				  (u8)conn_state->cp_content_type,
+				  conn_state->cp_srm_blob_id);
 }
 
 static void intel_disable_ddi_dp(struct intel_encoder *encoder,
@@ -3570,7 +3571,8 @@ static void intel_ddi_update_hdcp(struct intel_encoder *encoder,
 	if (conn_state->content_protection ==
 	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
 		intel_hdcp_enable(to_intel_connector(conn_state->connector),
-				  (u8)conn_state->cp_content_type);
+				  (u8)conn_state->cp_content_type,
+				  conn_state->cp_srm_blob_id);
 	else if (conn_state->content_protection ==
 		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
 		intel_hdcp_disable(to_intel_connector(conn_state->connector));
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 04cff672aead..53a463d40f43 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -482,6 +482,11 @@ struct intel_hdcp {
 	wait_queue_head_t cp_irq_queue;
 	atomic_t cp_irq_count;
 	int cp_irq_count_cached;
+
+	/* list of Revocated KSVs and their count from SRM blob Parsing */
+	unsigned int revocated_ksv_cnt;
+	u8 *revocated_ksv_list;
+	u32 srm_blob_id;
 };
 
 struct intel_connector {
@@ -2151,7 +2156,8 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
 			     struct drm_connector_state *new_state);
 int intel_hdcp_init(struct intel_connector *connector,
 		    const struct intel_hdcp_shim *hdcp_shim);
-int intel_hdcp_enable(struct intel_connector *connector, u8 content_type);
+int intel_hdcp_enable(struct intel_connector *connector, u8 content_type,
+		      u32 srm_blob_id);
 int intel_hdcp_disable(struct intel_connector *connector);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
 bool intel_hdcp_capable(struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index ab25264a74a4..4b12274d8987 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1805,6 +1805,10 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (ret)
 		return ret;
 
+	ret = drm_connector_attach_cp_srm_property(&connector->base);
+	if (ret)
+		return ret;
+
 	hdcp->shim = shim;
 	mutex_init(&hdcp->mutex);
 	INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work);
@@ -1817,7 +1821,144 @@ int intel_hdcp_init(struct intel_connector *connector,
 	return 0;
 }
 
-int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
+static u32 intel_hdcp_get_revocated_ksv_count(u8 *buf, u32 vrls_length)
+{
+	u32 parsed_bytes = 0, ksv_count = 0, vrl_ksv_cnt, vrl_sz;
+
+	do {
+		vrl_ksv_cnt = *buf;
+		ksv_count += vrl_ksv_cnt;
+
+		vrl_sz = (vrl_ksv_cnt * DRM_HDCP_KSV_LEN) + 1;
+		buf += vrl_sz;
+		parsed_bytes += vrl_sz;
+	} while (parsed_bytes < vrls_length);
+
+	return ksv_count;
+}
+
+static u32 intel_hdcp_get_revocated_ksvs(u8 *ksv_list, const u8 *buf,
+					 u32 vrls_length)
+{
+	u32 parsed_bytes = 0, ksv_count = 0;
+	u32 vrl_ksv_cnt, vrl_ksv_sz, vrl_idx = 0;
+
+	do {
+		vrl_ksv_cnt = *buf;
+		vrl_ksv_sz = vrl_ksv_cnt * DRM_HDCP_KSV_LEN;
+		buf++;
+
+		DRM_DEBUG_KMS("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
+			      vrl_ksv_cnt);
+		memcpy(ksv_list, buf, vrl_ksv_sz);
+		ksv_count += vrl_ksv_cnt;
+		ksv_list += vrl_ksv_sz;
+		buf += vrl_ksv_sz;
+
+		parsed_bytes += (vrl_ksv_sz + 1);
+	} while (parsed_bytes < vrls_length);
+
+	return ksv_count;
+}
+
+static int intel_hdcp_parse_srm(struct drm_connector *connector,
+				struct drm_property_blob *blob)
+{
+	struct intel_hdcp *hdcp = &(to_intel_connector(connector)->hdcp);
+	struct hdcp_srm_header *header;
+	u32 vrl_length, ksv_count;
+	u8 *buf;
+
+	if (blob->length < (sizeof(struct hdcp_srm_header) +
+	    DRM_HDCP_1_4_VRL_LENGTH_SIZE + DRM_HDCP_1_4_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length\n");
+		return -EINVAL;
+	}
+
+	header = (struct hdcp_srm_header *)blob->data;
+
+	DRM_DEBUG_KMS("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
+		      header->spec_indicator.srm_id,
+		      __swab16(header->srm_version), header->srm_gen_no);
+	WARN_ON(header->spec_indicator.reserved_hi ||
+		header->spec_indicator.reserved_lo);
+
+	if (header->spec_indicator.srm_id != DRM_HDCP_1_4_SRM_ID) {
+		DRM_ERROR("Invalid srm_id\n");
+		return -EINVAL;
+	}
+
+	buf = blob->data + sizeof(*header);
+	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));
+	if (blob->length < (sizeof(struct hdcp_srm_header) + vrl_length) ||
+	    vrl_length < (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
+			  DRM_HDCP_1_4_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length or vrl length\n");
+		return -EINVAL;
+	}
+
+	/* Length of the all vrls combined */
+	vrl_length -= (DRM_HDCP_1_4_VRL_LENGTH_SIZE +
+		       DRM_HDCP_1_4_DCP_SIG_SIZE);
+	if (!vrl_length) {
+		DRM_DEBUG("No vrl found\n");
+		return -EINVAL;
+	}
+	buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
+
+	ksv_count = intel_hdcp_get_revocated_ksv_count(buf, vrl_length);
+	if (!ksv_count) {
+		DRM_DEBUG_KMS("Revocated KSV count is 0\n");
+		return 0;
+	}
+
+	kfree(hdcp->revocated_ksv_list);
+	hdcp->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
+					   GFP_KERNEL);
+	if (!hdcp->revocated_ksv_list) {
+		DRM_ERROR("Out of Memory\n");
+		return -ENOMEM;
+	}
+
+	if (intel_hdcp_get_revocated_ksvs(hdcp->revocated_ksv_list,
+					  buf, vrl_length) != ksv_count) {
+		hdcp->revocated_ksv_cnt = 0;
+		kfree(hdcp->revocated_ksv_list);
+		return -EINVAL;
+	}
+
+	hdcp->revocated_ksv_cnt = ksv_count;
+	return 0;
+}
+
+static void intel_hdcp_update_srm(struct intel_connector *intel_connector,
+				  u32 srm_blob_id)
+{
+	struct drm_connector *connector = &intel_connector->base;
+	struct intel_hdcp *hdcp = &intel_connector->hdcp;
+	struct drm_property_blob *blob;
+
+	DRM_DEBUG_KMS("srm_blob_id %u\n", srm_blob_id);
+
+	if (!srm_blob_id) {
+		kfree(hdcp->revocated_ksv_list);
+		hdcp->revocated_ksv_cnt = 0;
+		hdcp->srm_blob_id = srm_blob_id;
+		return;
+	}
+
+	blob = drm_property_lookup_blob(connector->dev, srm_blob_id);
+	if (!blob || !blob->data)
+		return;
+
+	if (!intel_hdcp_parse_srm(connector, blob))
+		hdcp->srm_blob_id = srm_blob_id;
+
+	drm_property_blob_put(blob);
+}
+
+int intel_hdcp_enable(struct intel_connector *connector, u8 content_type,
+		      u32 srm_blob_id)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
@@ -1828,9 +1969,11 @@ int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
 
 	mutex_lock(&hdcp->mutex);
 	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
-
 	hdcp->content_type = content_type;
 
+	if (srm_blob_id != hdcp->srm_blob_id)
+		intel_hdcp_update_srm(connector, srm_blob_id);
+
 	/*
 	 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
 	 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index f243408ecf26..1ccae47fcff5 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -265,4 +265,18 @@ void drm_hdcp2_u32_to_seq_num(u8 seq_num[HDCP_2_2_SEQ_NUM_LEN], u32 val)
 	seq_num[2] = val;
 }
 
+#define DRM_HDCP_1_4_SRM_ID			0x8
+#define DRM_HDCP_1_4_VRL_LENGTH_SIZE		3
+#define DRM_HDCP_1_4_DCP_SIG_SIZE		40
+
+struct hdcp_srm_header {
+	struct {
+		u8 reserved_hi:4;
+		u8 srm_id:4;
+		u8 reserved_lo;
+	} spec_indicator;
+	u16 srm_version;
+	u8 srm_gen_no;
+} __packed;
+
 #endif
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 05/10] drm/i915: Add revocation check on HDCP1.4 Ksvs
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
                   ` (3 preceding siblings ...)
  2019-02-26  7:36 ` [PATCH 04/10] drm/i915: Add HDCP SRM Blob parsing Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-02-26  7:36 ` [PATCH 06/10] drm/i915: SRM parsing and revocation check for HDCP2 Ramalingam C
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

KSV list revocated by DCP LLC is provided as SRM Blob to kernel.
Which is parsed and stored in intel_hdcp->revocated_ksv_list.

This patch adds the revocation check for BKSV and KSV_FIFO in HDCP1.4
authentication.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_hdcp.c | 67 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 59 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 4b12274d8987..7d007de984d7 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -273,6 +273,45 @@ u32 intel_hdcp_get_repeater_ctl(struct intel_digital_port *intel_dig_port)
 	return -EINVAL;
 }
 
+static inline void intel_hdcp_print_ksv(u8 *ksv)
+{
+	DRM_DEBUG_KMS("\t%#04x, %#04x, %#04x, %#04x, %#04x\n", *ksv,
+		      *(ksv + 1), *(ksv + 2), *(ksv + 3), *(ksv + 4));
+}
+
+/* Check if any of the KSV is revocated by DCP LLC through SRM table */
+static inline
+bool intel_hdcp_ksvs_revocated(struct intel_hdcp *hdcp, u8 *ksvs, u32 ksv_count)
+{
+	u32 rev_ksv_cnt = hdcp->revocated_ksv_cnt;
+	u8 *rev_ksv_list = hdcp->revocated_ksv_list;
+	u32 cnt, i, j;
+
+	/* If the Revocated ksv list is empty */
+	if (!rev_ksv_cnt || !rev_ksv_list)
+		return false;
+
+	for  (cnt = 0; cnt < ksv_count; cnt++) {
+		rev_ksv_list = hdcp->revocated_ksv_list;
+		for (i = 0; i < rev_ksv_cnt; i++) {
+			for (j = 0; j < DRM_HDCP_KSV_LEN; j++)
+				if (*(ksvs + j) != *(rev_ksv_list + j)) {
+					break;
+				} else if (j == (DRM_HDCP_KSV_LEN - 1)) {
+					DRM_DEBUG_KMS("Revocated KSV is ");
+					intel_hdcp_print_ksv(ksvs);
+					return true;
+				}
+			/* Move the offset to next KSV in the revocated list */
+			rev_ksv_list += DRM_HDCP_KSV_LEN;
+		}
+
+		/* Iterate to next ksv_offset */
+		ksvs += DRM_HDCP_KSV_LEN;
+	}
+	return false;
+}
+
 static
 int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
 				const struct intel_hdcp_shim *shim,
@@ -490,9 +529,10 @@ int intel_hdcp_validate_v_prime(struct intel_digital_port *intel_dig_port,
 
 /* Implements Part 2 of the HDCP authorization procedure */
 static
-int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
-			       const struct intel_hdcp_shim *shim)
+int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp,
+			       struct intel_digital_port *intel_dig_port)
 {
+	const struct intel_hdcp_shim *shim = hdcp->shim;
 	u8 bstatus[2], num_downstream, *ksv_fifo;
 	int ret, i, tries = 3;
 
@@ -531,6 +571,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
 	if (ret)
 		goto err;
 
+	if (intel_hdcp_ksvs_revocated(hdcp, ksv_fifo, num_downstream)) {
+		DRM_ERROR("Revocated Ksv(s) in ksv_fifo\n");
+		return -EPERM;
+	}
+
 	/*
 	 * When V prime mismatches, DP Spec mandates re-read of
 	 * V prime atleast twice.
@@ -557,9 +602,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
 }
 
 /* Implements Part 1 of the HDCP authorization procedure */
-static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
-			   const struct intel_hdcp_shim *shim)
+static int intel_hdcp_auth(struct intel_connector *connector)
 {
+	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+	struct intel_hdcp *hdcp = &connector->hdcp;
+	const struct intel_hdcp_shim *shim = hdcp->shim;
 	struct drm_i915_private *dev_priv;
 	enum port port;
 	unsigned long r0_prime_gen_start;
@@ -625,6 +672,11 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
 	if (ret < 0)
 		return ret;
 
+	if (intel_hdcp_ksvs_revocated(hdcp, bksv.shim, 1)) {
+		DRM_ERROR("BKSV is revocated\n");
+		return -EPERM;
+	}
+
 	I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]);
 	I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]);
 
@@ -698,7 +750,7 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
 	 */
 
 	if (repeater_present)
-		return intel_hdcp_auth_downstream(intel_dig_port, shim);
+		return intel_hdcp_auth_downstream(hdcp, intel_dig_port);
 
 	DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n");
 	return 0;
@@ -735,7 +787,6 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 
 static int _intel_hdcp_enable(struct intel_connector *connector)
 {
-	struct intel_hdcp *hdcp = &connector->hdcp;
 	struct drm_i915_private *dev_priv = connector->base.dev->dev_private;
 	int i, ret, tries = 3;
 
@@ -760,9 +811,9 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
 
 	/* Incase of authentication failures, HDCP spec expects reauth. */
 	for (i = 0; i < tries; i++) {
-		ret = intel_hdcp_auth(conn_to_dig_port(connector), hdcp->shim);
+		ret = intel_hdcp_auth(connector);
 		if (!ret) {
-			hdcp->hdcp_encrypted = true;
+			connector->hdcp.hdcp_encrypted = true;
 			return 0;
 		}
 
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 06/10] drm/i915: SRM parsing and revocation check for HDCP2
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
                   ` (4 preceding siblings ...)
  2019-02-26  7:36 ` [PATCH 05/10] drm/i915: Add revocation check on HDCP1.4 Ksvs Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-02-26  7:36 ` [PATCH 07/10] drm: Add CP downstream_info property Ramalingam C
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

SRM blob with hdcp2 id is parsed and parsed list of revoked ids is
used in the authentication process to identify the compromised HDCP
sinks.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_hdcp.c | 86 +++++++++++++++++++++++++++++++++++++--
 include/drm/drm_hdcp.h            | 20 +++++++++
 2 files changed, 103 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 7d007de984d7..b92fc0383788 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1244,6 +1244,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
 
 	hdcp->is_repeater = HDCP_2_2_RX_REPEATER(msgs.send_cert.rx_caps[2]);
 
+	if (intel_hdcp_ksvs_revocated(hdcp,
+				      msgs.send_cert.cert_rx.receiver_id, 1)) {
+		DRM_ERROR("Receiver ID is revocated\n");
+		return -EPERM;
+	}
+
 	/*
 	 * Here msgs.no_stored_km will hold msgs corresponding to the km
 	 * stored also.
@@ -1402,7 +1408,7 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 	} msgs;
 	const struct intel_hdcp_shim *shim = hdcp->shim;
 	u8 *rx_info;
-	u32 seq_num_v;
+	u32 seq_num_v, device_cnt;
 	int ret;
 
 	ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_REP_SEND_RECVID_LIST,
@@ -1427,6 +1433,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 		return -EINVAL;
 	}
 
+	device_cnt = HDCP_2_2_DEV_COUNT_HI(rx_info[0]) << 4 ||
+			HDCP_2_2_DEV_COUNT_LO(rx_info[1]);
+	if (intel_hdcp_ksvs_revocated(hdcp, msgs.recvid_list.receiver_ids,
+				      device_cnt)) {
+		DRM_ERROR("Revoked receiver ID(s) is in list\n");
+		return -EPERM;
+	}
+
 	ret = hdcp2_verify_rep_topology_prepare_ack(connector,
 						    &msgs.recvid_list,
 						    &msgs.rep_ack);
@@ -1982,12 +1996,72 @@ static int intel_hdcp_parse_srm(struct drm_connector *connector,
 	return 0;
 }
 
+static int intel_hdcp2_parse_srm(struct drm_connector *connector,
+				 struct drm_property_blob *blob)
+{
+	struct intel_hdcp *hdcp = &(to_intel_connector(connector)->hdcp);
+	struct hdcp2_srm_header *header;
+	u32 vrl_length, ksv_count, ksv_sz;
+	u8 *buf;
+
+	if (blob->length < (sizeof(struct hdcp2_srm_header) +
+	    DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length\n");
+		return -EINVAL;
+	}
+
+	header = (struct hdcp2_srm_header *)blob->data;
+	DRM_DEBUG_KMS("SRM ID: 0x%x, SRM Ver: 0x%x, SRM Gen No: 0x%x\n",
+		      header->spec_indicator.srm_id,
+		      __swab16(header->srm_version), header->srm_gen_no);
+	WARN_ON(header->spec_indicator.reserved);
+	buf = blob->data + sizeof(*header);
+
+	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));
+	if (blob->length < (sizeof(struct hdcp2_srm_header) + vrl_length) ||
+	    vrl_length < (DRM_HDCP_2_VRL_LENGTH_SIZE +
+			  DRM_HDCP_2_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length or vrl length\n");
+		return -EINVAL;
+	}
+
+	/* Length of the all vrls combined */
+	vrl_length -= (DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE);
+	if (!vrl_length) {
+		DRM_ERROR("No vrl found\n");
+		return -EINVAL;
+	}
+
+	buf += DRM_HDCP_2_VRL_LENGTH_SIZE;
+	ksv_count = (*buf << 2) | DRM_HDCP_2_KSV_COUNT_2_LSBITS(*(buf + 1));
+	if (!ksv_count)
+		return 0;
+
+	kfree(hdcp->revocated_ksv_list);
+	hdcp->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
+					   GFP_KERNEL);
+	if (!hdcp->revocated_ksv_list) {
+		DRM_ERROR("Out of Memory\n");
+		return -ENOMEM;
+	}
+
+	ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
+	buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
+
+	DRM_DEBUG_KMS("Revoked KSVs: %d\n", ksv_count);
+	memcpy(hdcp->revocated_ksv_list, buf, ksv_sz);
+	hdcp->revocated_ksv_cnt = ksv_count;
+
+	return 0;
+}
+
 static void intel_hdcp_update_srm(struct intel_connector *intel_connector,
 				  u32 srm_blob_id)
 {
 	struct drm_connector *connector = &intel_connector->base;
 	struct intel_hdcp *hdcp = &intel_connector->hdcp;
 	struct drm_property_blob *blob;
+	u8 srm_id;
 
 	DRM_DEBUG_KMS("srm_blob_id %u\n", srm_blob_id);
 
@@ -2002,8 +2076,14 @@ static void intel_hdcp_update_srm(struct intel_connector *intel_connector,
 	if (!blob || !blob->data)
 		return;
 
-	if (!intel_hdcp_parse_srm(connector, blob))
-		hdcp->srm_blob_id = srm_blob_id;
+	srm_id = *((u8 *)blob->data);
+	if (srm_id == DRM_HDCP_SRM_ID) {
+		if (!intel_hdcp_parse_srm(connector, blob))
+			hdcp->srm_blob_id = srm_blob_id;
+	} else if (srm_id == DRM_HDCP2_SRM_ID) {
+		if (!intel_hdcp2_parse_srm(connector, blob))
+			hdcp->srm_blob_id = srm_blob_id;
+	}
 
 	drm_property_blob_put(blob);
 }
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 1ccae47fcff5..1e630a593b73 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -279,4 +279,24 @@ struct hdcp_srm_header {
 	u8 srm_gen_no;
 } __packed;
 
+#define DRM_HDCP_2_SRM_ID			0x9
+#define DRM_HDCP_2_INDICATOR			0x1
+#define DRM_HDCP_2_VRL_LENGTH_SIZE		3
+#define DRM_HDCP_2_DCP_SIG_SIZE			384
+#define DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ	4
+
+#define DRM_HDCP_2_KSV_COUNT_2_LSBITS(byte)	(((byte) & 0xC) >> 6)
+#define DRM_HDCP_SRM_ID				0x80
+#define DRM_HDCP2_SRM_ID			0x91
+
+struct hdcp2_srm_header {
+	struct {
+		u8 hdcp2_indicator:4;
+		u8 srm_id:4;
+		u8 reserved;
+	} spec_indicator;
+	u16 srm_version;
+	u8 srm_gen_no;
+} __packed;
+
 #endif
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 07/10] drm: Add CP downstream_info property
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
                   ` (5 preceding siblings ...)
  2019-02-26  7:36 ` [PATCH 06/10] drm/i915: SRM parsing and revocation check for HDCP2 Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-02-26  7:36 ` [PATCH 08/10] drm/i915: Populate downstream info for HDCP1.4 Ramalingam C
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

This patch adds CP downstream info blob property to the
connectors. This enables the Userspace to read the information of HDCP
authenticated downstream topology.

Driver will updated this blob with all downstream information at the
end of the authentication.

Userspace need this informations to configure this platform as repeater,
where KMD will be the downstream HDCP ports of the repeater and userspace
implementation will act as upstream HDCP port.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/drm_atomic_uapi.c |  3 ++
 drivers/gpu/drm/drm_connector.c   | 88 +++++++++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h       | 12 ++++++
 include/uapi/drm/drm_mode.h       | 27 ++++++++++++
 4 files changed, 130 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 9c57d8c07d09..f28fb64d1986 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -842,6 +842,9 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->cp_content_type;
 	} else if (property == connector->cp_srm_property) {
 		*val = state->cp_srm_blob_id;
+	} else if (property == connector->cp_downstream_property) {
+		*val = connector->cp_downstream_blob_ptr ?
+			connector->cp_downstream_blob_ptr->base.id : 0;
 	} else if (property == config->writeback_fb_id_property) {
 		/* Writeback framebuffer is one-shot, write and forget */
 		*val = 0;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 510941ad532f..0b58d07d1d53 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -245,6 +245,7 @@ int drm_connector_init(struct drm_device *dev,
 	INIT_LIST_HEAD(&connector->modes);
 	mutex_init(&connector->mutex);
 	connector->edid_blob_ptr = NULL;
+	connector->cp_downstream_blob_ptr = NULL;
 	connector->status = connector_status_unknown;
 	connector->display_info.panel_orientation =
 		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
@@ -1002,6 +1003,25 @@ DRM_ENUM_NAME_FN(drm_get_cp_content_type_name, drm_cp_content_type_enum_list)
  *	Guideline for programming:
  *	  - Property state can be changed only when "Content Protection state is
  *		DRM_MODE_CONTENT_PROTECTION_UNDESIRED.
+ * CP_Downstream_Info:
+ *	This blob property is used to pass the HDCP downstream topology details
+ *	of a HDCP encrypted connector, from kernel to userspace.
+ *	This provides all required information to userspace, so that userspace
+ *	can implement the HDCP repeater using the kernel as downstream ports of
+ *	the repeater. as illustrated below:
+ *
+ *                          HDCP Repeaters
+ * +--------------------------------------------------------------+
+ * |                                                              |
+ * |                               |                              |
+ * |   Userspace HDCP Receiver  +----->    KMD HDCP transmitters  |
+ * |      (Upstream Port)      <------+     (Downstream Ports)    |
+ * |                               |                              |
+ * |                                                              |
+ * +--------------------------------------------------------------+
+ *
+ *	Kernel will populate this blob only when the HDCP authentication is
+ *	successful.
  *
  * max bpc:
  *	This range property is used by userspace to limit the bit depth. When
@@ -1664,6 +1684,74 @@ int drm_connector_attach_cp_srm_property(struct drm_connector *connector)
 EXPORT_SYMBOL(drm_connector_attach_cp_srm_property);
 
 /**
+ * drm_connector_attach_cp_downstream_property - attach cp downstream
+ * property
+ *
+ * @connector: connector to attach cp downstream property on.
+ *
+ * This is used to add support for content protection downstream info on
+ * select connectors. when Intel platform is configured as repeater,
+ * this downstream info is used by userspace, to complete the repeater
+ * authentication of HDCP specification with upstream HDCP transmitter.
+ *
+ * The cp downstream will be set to &drm_connector_state.cp_downstream
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_cp_downstream_property(
+		struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop;
+
+	prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
+				   DRM_MODE_PROP_IMMUTABLE,
+				   "CP_Downstream_Info", 0);
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop, 0);
+
+	connector->cp_downstream_property = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_cp_downstream_property);
+
+/**
+ * drm_mode_connector_update_cp_downstream_property - update the cp_downstream
+ *			property of a connector
+ * @connector: drm connector
+ * @cp_downstream_info: new value of the cp_downstream property
+ *
+ * This function creates a new blob modeset object and assigns its id to the
+ * connector's cp_downstream property.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_mode_connector_update_cp_downstream_property(
+			struct drm_connector *connector,
+			const struct cp_downstream_info *info)
+{
+	struct drm_device *dev = connector->dev;
+	int ret;
+
+	if (!info)
+		return -EINVAL;
+
+	ret = drm_property_replace_global_blob(dev,
+					&connector->cp_downstream_blob_ptr,
+					sizeof(struct cp_downstream_info),
+					info,
+					&connector->base,
+					connector->cp_downstream_property);
+	return ret;
+}
+EXPORT_SYMBOL(drm_mode_connector_update_cp_downstream_property);
+
+/**
  * drm_mode_create_aspect_ratio_property - create aspect ratio property
  * @dev: DRM device
  *
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 796e5d5e9e5f..4ea433e779d8 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1060,6 +1060,13 @@ struct drm_connector {
 	struct drm_property *cp_srm_property;
 
 	/**
+	 * @cp_downstream_property: DRM BLOB property for content
+	 * protection downstream information.
+	 */
+	struct drm_property *cp_downstream_property;
+	struct drm_property_blob *cp_downstream_blob_ptr;
+
+	/**
 	 * @path_blob_ptr:
 	 *
 	 * DRM blob property data for the DP MST path property. This should only
@@ -1337,6 +1344,11 @@ int drm_connector_attach_content_protection_property(
 int drm_connector_attach_cp_content_type_property(
 		struct drm_connector *connector);
 int drm_connector_attach_cp_srm_property(struct drm_connector *connector);
+int drm_connector_attach_cp_downstream_property(
+		struct drm_connector *connector);
+int drm_mode_connector_update_cp_downstream_property(
+		struct drm_connector *connector,
+		const struct cp_downstream_info *info);
 int drm_mode_create_aspect_ratio_property(struct drm_device *dev);
 int drm_mode_create_colorspace_property(struct drm_connector *connector);
 int drm_mode_create_content_type_property(struct drm_device *dev);
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 8504e3110e19..aae84d025518 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -214,6 +214,33 @@ extern "C" {
 #define DRM_MODE_CP_CONTENT_TYPE0		0
 #define DRM_MODE_CP_CONTENT_TYPE1		1
 
+#define DRM_MODE_HDCP_KSV_LEN			5
+#define DRM_MODE_HDCP_MAX_DEVICE_CNT		127
+
+struct cp_downstream_info {
+	/* KSV of immediate HDCP Sink. In Little-Endian Format. */
+	char bksv[DRM_MODE_HDCP_KSV_LEN];
+
+	/* Whether Immediate HDCP sink is a repeater? */
+	bool is_repeater;
+
+	/* Depth received from immediate downstream repeater */
+	__u8 depth;
+
+	/* Device count received from immediate downstream repeater */
+	__u32 device_count;
+
+	/*
+	 * Max buffer required to hold ksv list received from immediate
+	 * repeater. In this array first device_count * DRM_MODE_HDCP_KSV_LEN
+	 * will hold the valid ksv bytes.
+	 * If authentication specification is
+	 *	HDCP1.4 - each KSV's Bytes will be in Little-Endian format.
+	 *	HDCP2.2 - each KSV's Bytes will be in Big-Endian format.
+	 */
+	char ksv_list[DRM_MODE_HDCP_KSV_LEN * DRM_MODE_HDCP_MAX_DEVICE_CNT];
+};
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 08/10] drm/i915: Populate downstream info for HDCP1.4
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
                   ` (6 preceding siblings ...)
  2019-02-26  7:36 ` [PATCH 07/10] drm: Add CP downstream_info property Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-02-26  7:36 ` [PATCH 09/10] drm/i915: Populate downstream info for HDCP2.2 Ramalingam C
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

Implements drm blob property cp_downstream_info property on HDCP
capable connectors.

Downstream topology info is gathered across authentication stages
and stored in intel_hdcp. When HDCP authentication is complete,
new blob with latest downstream topology information is updated to
cp_downstream_info property.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_drv.h  |  2 ++
 drivers/gpu/drm/i915/intel_hdcp.c | 32 +++++++++++++++++++++++++++++++-
 include/drm/drm_hdcp.h            |  1 +
 include/uapi/drm/drm_mode.h       |  5 +++++
 4 files changed, 39 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index 53a463d40f43..c7ef7e71439d 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -487,6 +487,8 @@ struct intel_hdcp {
 	unsigned int revocated_ksv_cnt;
 	u8 *revocated_ksv_list;
 	u32 srm_blob_id;
+
+	struct cp_downstream_info *downstream_info;
 };
 
 struct intel_connector {
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index b92fc0383788..9ce634e552c1 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -563,6 +563,9 @@ int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp,
 	if (num_downstream == 0)
 		return -EINVAL;
 
+	hdcp->downstream_info->device_count = num_downstream;
+	hdcp->downstream_info->depth = DRM_HDCP_DEPTH(bstatus[1]);
+
 	ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL);
 	if (!ksv_fifo)
 		return -ENOMEM;
@@ -576,6 +579,8 @@ int intel_hdcp_auth_downstream(struct intel_hdcp *hdcp,
 		return -EPERM;
 	}
 
+	memcpy(hdcp->downstream_info->ksv_list, ksv_fifo,
+	       num_downstream * DRM_HDCP_KSV_LEN);
 	/*
 	 * When V prime mismatches, DP Spec mandates re-read of
 	 * V prime atleast twice.
@@ -677,15 +682,20 @@ static int intel_hdcp_auth(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	hdcp->downstream_info->ver_in_force = DRM_MODE_HDCP14_IN_FORCE;
+	memcpy(hdcp->downstream_info->bksv, bksv.shim, DRM_MODE_HDCP_KSV_LEN);
+
 	I915_WRITE(PORT_HDCP_BKSVLO(port), bksv.reg[0]);
 	I915_WRITE(PORT_HDCP_BKSVHI(port), bksv.reg[1]);
 
 	ret = shim->repeater_present(intel_dig_port, &repeater_present);
 	if (ret)
 		return ret;
-	if (repeater_present)
+	if (repeater_present) {
 		I915_WRITE(HDCP_REP_CTL,
 			   intel_hdcp_get_repeater_ctl(intel_dig_port));
+		hdcp->downstream_info->is_repeater = true;
+	}
 
 	ret = shim->toggle_signalling(intel_dig_port, true);
 	if (ret)
@@ -781,6 +791,13 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 		return ret;
 	}
 
+	memset(hdcp->downstream_info, 0, sizeof(struct cp_downstream_info));
+
+	if (drm_mode_connector_update_cp_downstream_property(
+				&connector->base,
+				connector->hdcp.downstream_info))
+		DRM_ERROR("Downstream_info update failed.\n");
+
 	DRM_DEBUG_KMS("HDCP is disabled\n");
 	return 0;
 }
@@ -814,6 +831,10 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
 		ret = intel_hdcp_auth(connector);
 		if (!ret) {
 			connector->hdcp.hdcp_encrypted = true;
+			if (drm_mode_connector_update_cp_downstream_property(
+					&connector->base,
+					connector->hdcp.downstream_info))
+				DRM_ERROR("Downstream_info update failed.\n");
 			return 0;
 		}
 
@@ -1874,6 +1895,15 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (ret)
 		return ret;
 
+	ret = drm_connector_attach_cp_downstream_property(&connector->base);
+	if (ret)
+		return ret;
+
+	hdcp->downstream_info = kzalloc(sizeof(*hdcp->downstream_info),
+					GFP_KERNEL);
+	if (!hdcp->downstream_info)
+		return -ENOMEM;
+
 	hdcp->shim = shim;
 	mutex_init(&hdcp->mutex);
 	INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work);
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 1e630a593b73..2787a2d555b4 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -23,6 +23,7 @@
 #define DRM_HDCP_V_PRIME_PART_LEN		4
 #define DRM_HDCP_V_PRIME_NUM_PARTS		5
 #define DRM_HDCP_NUM_DOWNSTREAM(x)		(x & 0x7f)
+#define DRM_HDCP_DEPTH(x)			((x) & 0x7)
 #define DRM_HDCP_MAX_CASCADE_EXCEEDED(x)	(x & BIT(3))
 #define DRM_HDCP_MAX_DEVICE_EXCEEDED(x)		(x & BIT(7))
 
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index aae84d025518..93403b2631ef 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -216,8 +216,13 @@ extern "C" {
 
 #define DRM_MODE_HDCP_KSV_LEN			5
 #define DRM_MODE_HDCP_MAX_DEVICE_CNT		127
+#define DRM_MODE_HDCP14_IN_FORCE		(1 << 0)
+#define DRM_MODE_HDCP22_IN_FORCE		(1 << 1)
 
 struct cp_downstream_info {
+	/* Version of HDCP authenticated (1.4/2.2) */
+	__u32 ver_in_force;
+
 	/* KSV of immediate HDCP Sink. In Little-Endian Format. */
 	char bksv[DRM_MODE_HDCP_KSV_LEN];
 
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 09/10] drm/i915: Populate downstream info for HDCP2.2
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
                   ` (7 preceding siblings ...)
  2019-02-26  7:36 ` [PATCH 08/10] drm/i915: Populate downstream info for HDCP1.4 Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-02-26  7:36 ` [PATCH 10/10] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
  2019-02-26  8:24 ` [PATCH 00/10] HDCP2.2 Phase II Daniel Vetter
  10 siblings, 0 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

Populates the downstream info for HDCP2.2 encryption also. On success
of encryption Blob is updated.

Additional two variable are added to downstream info blob. Such as
ver_in_force and content type.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/intel_hdcp.c | 29 ++++++++++++++++++++++++++++-
 include/uapi/drm/drm_mode.h       |  3 +++
 2 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 9ce634e552c1..8c05f382718c 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1271,6 +1271,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	hdcp->downstream_info->ver_in_force = DRM_MODE_HDCP22_IN_FORCE;
+	hdcp->downstream_info->content_type = hdcp->content_type;
+	memcpy(hdcp->downstream_info->bksv, msgs.send_cert.cert_rx.receiver_id,
+	       HDCP_2_2_RECEIVER_ID_LEN);
+	hdcp->downstream_info->is_repeater = hdcp->is_repeater;
+
 	/*
 	 * Here msgs.no_stored_km will hold msgs corresponding to the km
 	 * stored also.
@@ -1462,6 +1468,11 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	hdcp->downstream_info->device_count = device_cnt;
+	hdcp->downstream_info->depth = HDCP_2_2_DEPTH(rx_info[0]);
+	memcpy(hdcp->downstream_info->ksv_list, msgs.recvid_list.receiver_ids,
+	       device_cnt * HDCP_2_2_RECEIVER_ID_LEN);
+
 	ret = hdcp2_verify_rep_topology_prepare_ack(connector,
 						    &msgs.recvid_list,
 						    &msgs.rep_ack);
@@ -1648,6 +1659,13 @@ static int _intel_hdcp2_enable(struct intel_connector *connector)
 	if (ret) {
 		DRM_DEBUG_KMS("HDCP2 Type%d  Enabling Failed. (%d)\n",
 			      hdcp->content_type, ret);
+
+		memset(hdcp->downstream_info, 0,
+		       sizeof(struct cp_downstream_info));
+		drm_mode_connector_update_cp_downstream_property(
+					&connector->base,
+					hdcp->downstream_info);
+
 		return ret;
 	}
 
@@ -1655,12 +1673,17 @@ static int _intel_hdcp2_enable(struct intel_connector *connector)
 		      connector->base.name, connector->base.base.id,
 		      hdcp->content_type);
 
+	drm_mode_connector_update_cp_downstream_property(
+					&connector->base,
+					hdcp->downstream_info);
 	hdcp->hdcp2_encrypted = true;
+
 	return 0;
 }
 
 static int _intel_hdcp2_disable(struct intel_connector *connector)
 {
+	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret;
 
 	DRM_DEBUG_KMS("[%s:%d] HDCP2.2 is being Disabled\n",
@@ -1671,8 +1694,12 @@ static int _intel_hdcp2_disable(struct intel_connector *connector)
 	if (hdcp2_deauthenticate_port(connector) < 0)
 		DRM_DEBUG_KMS("Port deauth failed.\n");
 
-	connector->hdcp.hdcp2_encrypted = false;
+	hdcp->hdcp2_encrypted = false;
 
+	memset(hdcp->downstream_info, 0, sizeof(struct cp_downstream_info));
+	drm_mode_connector_update_cp_downstream_property(
+					&connector->base,
+					hdcp->downstream_info);
 	return ret;
 }
 
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 93403b2631ef..4d868de06f8f 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -223,6 +223,9 @@ struct cp_downstream_info {
 	/* Version of HDCP authenticated (1.4/2.2) */
 	__u32 ver_in_force;
 
+	/* Applicable only for HDCP2.2 */
+	__u8 content_type;
+
 	/* KSV of immediate HDCP Sink. In Little-Endian Format. */
 	char bksv[DRM_MODE_HDCP_KSV_LEN];
 
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH 10/10] drm/i915: debugfs: HDCP2.2 capability read
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
                   ` (8 preceding siblings ...)
  2019-02-26  7:36 ` [PATCH 09/10] drm/i915: Populate downstream info for HDCP2.2 Ramalingam C
@ 2019-02-26  7:36 ` Ramalingam C
  2019-02-26  8:24 ` [PATCH 00/10] HDCP2.2 Phase II Daniel Vetter
  10 siblings, 0 replies; 15+ messages in thread
From: Ramalingam C @ 2019-02-26  7:36 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel.vetter, uma.shankar

Adding the HDCP2.2 capability of HDCP src and sink info into debugfs
entry "i915_hdcp_sink_capability"

This helps the userspace tests to skip the HDCP2.2 test on non HDCP2.2
sinks.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 13 +++++++++++--
 drivers/gpu/drm/i915/intel_drv.h    |  1 +
 drivers/gpu/drm/i915/intel_hdcp.c   |  2 +-
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c
index 37175414ce89..b2fff7be7407 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4762,6 +4762,7 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
 {
 	struct drm_connector *connector = m->private;
 	struct intel_connector *intel_connector = to_intel_connector(connector);
+	bool hdcp_cap, hdcp2_cap;
 
 	if (connector->status != connector_status_connected)
 		return -ENODEV;
@@ -4772,8 +4773,16 @@ static int i915_hdcp_sink_capability_show(struct seq_file *m, void *data)
 
 	seq_printf(m, "%s:%d HDCP version: ", connector->name,
 		   connector->base.id);
-	seq_printf(m, "%s ", !intel_hdcp_capable(intel_connector) ?
-		   "None" : "HDCP1.4");
+	hdcp_cap = intel_hdcp_capable(intel_connector);
+	hdcp2_cap = intel_hdcp2_capable(intel_connector);
+
+	if (hdcp_cap)
+		seq_puts(m, "HDCP1.4 ");
+	if (hdcp2_cap)
+		seq_puts(m, "HDCP2.2 ");
+
+	if (!hdcp_cap && !hdcp2_cap)
+		seq_puts(m, "None");
 	seq_puts(m, "\n");
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index c7ef7e71439d..fb055d688cdf 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -2163,6 +2163,7 @@ int intel_hdcp_enable(struct intel_connector *connector, u8 content_type,
 int intel_hdcp_disable(struct intel_connector *connector);
 bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
 bool intel_hdcp_capable(struct intel_connector *connector);
+bool intel_hdcp2_capable(struct intel_connector *connector);
 void intel_hdcp_component_init(struct drm_i915_private *dev_priv);
 void intel_hdcp_component_fini(struct drm_i915_private *dev_priv);
 void intel_hdcp_cleanup(struct intel_connector *connector);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 8c05f382718c..29175ccddc92 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -76,7 +76,7 @@ bool intel_hdcp_capable(struct intel_connector *connector)
 }
 
 /* Is HDCP2.2 capable on Platform and Sink */
-static bool intel_hdcp2_capable(struct intel_connector *connector)
+bool intel_hdcp2_capable(struct intel_connector *connector)
 {
 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
-- 
2.7.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH 00/10] HDCP2.2 Phase II
  2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
                   ` (9 preceding siblings ...)
  2019-02-26  7:36 ` [PATCH 10/10] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
@ 2019-02-26  8:24 ` Daniel Vetter
  10 siblings, 0 replies; 15+ messages in thread
From: Daniel Vetter @ 2019-02-26  8:24 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Tue, Feb 26, 2019 at 8:42 AM Ramalingam C <ramalingam.c@intel.com> wrote:
>
> HDCP2.2 phase-II mojorly adds below features:
>         Addition of three connector properties
>                 CP_Content_Type
>                 CP_SRM

Not really clear why this is a connector property. Do we need
different SRM for different connectors? My understanding of the spec
is that we want one SRM globally (so not even per driver). I think a
binary sysfs file in the drm class (in /sys/class/drm, not one of the
subdirectories) would fit that. Plus make userspace simpler, since a
cat srm_file > /sys/class/drm/cp_srm at boot-up is all we need.

Drivers can then just check with drm core for the latest srm file at
the start of each hdcp transaction, and update it if there is one.
Plus maybe a few functions to do sink filtering on the cpu - I think
we need that for hdcp1.x on i915 too.

Other properties make sense on the connector I think. Also please
spell out CP as content_protection in all the properties/interfaces, I
think that would be good, in common lingo (see urban dictionary) cp
has a different meaning.
-Daniel

>                 CP_Downstream_Info
>         parsing for HDCP1.4 and 2.2 SRM Blobs
>         Once HDCP1.4/2.2 authentication is completed gathering the all
>                 downstream topology for userspace
>         Extending debugfs entry to provide the HDCP2.2 capability too.
>
> CP_Content_Type:
>         This property is used to indicate the content type
> classification of a stream. Which indicate the HDCP version required
> for the rendering of that streams. This conten type is one of the
> parameter in the HDCP2.2 authentication flow, as even downstream
> repeaters will mandate the HDCP version requirement.
>
> Two values possible for content type of a stream:
>         Type 0: Stream can be rendered only on HDCP encrypted link no
>                 restriction on HDCP versions.
>         Type 1: Stream can be rendered only on HDCP2.2 encrypted link.
>
> There is a parallel effort in #wayland community to add the support for
> HDCP2.2 along with content type support. Patches are under review in
> #wayland community.
>
> CP_SRM:
> This blob property is used by the userspace to pass the SRM table
> of HDCP1.4 and 2.2. These are nothing but revocated list of receiver IDs
> of the HDCP sinks. KMD will use this list to identify the revocated
> devices in the HDCP authentication and deny the hdcp encryption to it.
>
> Work in progress to add the SRM support in the weston HDCP stack.
> Yet to publish the patches in the #wayland community.
>
> CP_Downstream_Info:
> This blob property is used by the kernel to pass the downstream topology
> of the HDCP encrypted port to the userspace.
>
> This is used by the userspace to implement the HDCP repeater, which KMD
> implementing the HDCP transmitters(downstream ports) and userspace
> implementing the upstream port(HDCP receiver).
>
> Discussion is on going to add the downstream_info support in the
> weston HDCP stack.
>
> Test-with: 1551165805-19130-2-git-send-email-ramalingam.c@intel.com
>
> Ramalingam C (10):
>   drm: Add CP content type property
>   drm/i915: Attach content type property
>   drm: Add CP System Renewability Msg Property
>   drm/i915: Add HDCP SRM Blob parsing
>   drm/i915: Add revocation check on HDCP1.4 Ksvs
>   drm/i915: SRM parsing and revocation check for HDCP2
>   drm: Add CP downstream_info property
>   drm/i915: Populate downstream info for HDCP1.4
>   drm/i915: Populate downstream info for HDCP2.2
>   drm/i915: debugfs: HDCP2.2 capability read
>
>  drivers/gpu/drm/drm_atomic_uapi.c   |  23 +++
>  drivers/gpu/drm/drm_connector.c     | 204 ++++++++++++++++++++
>  drivers/gpu/drm/i915/i915_debugfs.c |  13 +-
>  drivers/gpu/drm/i915/intel_ddi.c    |  23 ++-
>  drivers/gpu/drm/i915/intel_drv.h    |  11 +-
>  drivers/gpu/drm/i915/intel_hdcp.c   | 373 ++++++++++++++++++++++++++++++++++--
>  include/drm/drm_connector.h         |  40 ++++
>  include/drm/drm_hdcp.h              |  35 ++++
>  include/uapi/drm/drm_mode.h         |  39 ++++
>  9 files changed, 737 insertions(+), 24 deletions(-)
>
> --
> 2.7.4
>


-- 
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Intel-gfx] [PATCH 01/10] drm: Add CP content type property
  2019-02-26  7:36 ` [PATCH 01/10] drm: Add CP content type property Ramalingam C
@ 2019-03-05 14:39   ` Maarten Lankhorst
  2019-03-05 19:00     ` C, Ramalingam
  0 siblings, 1 reply; 15+ messages in thread
From: Maarten Lankhorst @ 2019-03-05 14:39 UTC (permalink / raw)
  To: Ramalingam C, intel-gfx, dri-devel, daniel.vetter, uma.shankar

Op 26-02-2019 om 08:36 schreef Ramalingam C:
> This patch adds a DRM ENUM property to the selected connectors.
> This property is used for pass the protected content's type
> from userspace to kernel HDCP authentication.
>
> Type of the stream is decided by the protected content providers as
> Type 0/1.
>
> 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 upon a content protection request with Type 1 as Content type from
> userspace, Kernel will declare success only if the HDCP2.2
> authentication is successful.
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic_uapi.c | 10 ++++++
>  drivers/gpu/drm/drm_connector.c   | 64 +++++++++++++++++++++++++++++++++++++++
>  include/drm/drm_connector.h       | 15 +++++++++
>  include/uapi/drm/drm_mode.h       |  4 +++
>  4 files changed, 93 insertions(+)
>
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index 4eb81f10bc54..5289486565ce 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -746,6 +746,14 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
>  			return -EINVAL;
>  		}
>  		state->content_protection = val;
> +	} else if (property == connector->cp_content_type_property) {
> +		if (state->content_protection !=
> +		    DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
> +		    state->cp_content_type != val) {
> +			DRM_DEBUG_KMS("Disable CP, then change Type\n");
> +			return -EINVAL;
> +		}
> +		state->cp_content_type = val;

You can't add checks in atomic_set_property.

Until we have the full state, we can't do any checks. This has to be done in the .atomic_check() callback.

Lets say atomic commit consists of the following:
Set Content_Protection to desired.
Set Content Type to Type 1.
atomic setprop will fail

Plus the check itself is bogus. We should be able to change HDCP strictness without a modeset, the same way
we enable and disable HDCP 1.4 with a fastset.

>  	} else if (property == connector->colorspace_property) {
>  		state->colorspace = val;
>  	} else if (property == config->writeback_fb_id_property) {
> @@ -822,6 +830,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
>  		*val = state->scaling_mode;
>  	} else if (property == connector->content_protection_property) {
>  		*val = state->content_protection;
> +	} else if (property == connector->cp_content_type_property) {
> +		*val = state->cp_content_type;
>  	} else if (property == config->writeback_fb_id_property) {
>  		/* Writeback framebuffer is one-shot, write and forget */
>  		*val = 0;
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 07d65a16c623..5d7738e1e977 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -853,6 +853,13 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
>  	{ DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER, "DCI-P3_RGB_Theater" },
>  };
>  
> +static struct drm_prop_enum_list drm_cp_content_type_enum_list[] = {
> +	{ DRM_MODE_CP_CONTENT_TYPE0, "Type 0" },
> +	{ DRM_MODE_CP_CONTENT_TYPE1, "Type 1" },
> +};
> +
> +DRM_ENUM_NAME_FN(drm_get_cp_content_type_name, drm_cp_content_type_enum_list)
> +
>  /**
>   * DOC: standard connector properties
>   *
> @@ -958,6 +965,25 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
>   *	  the value transitions from ENABLED to DESIRED. This signifies the link
>   *	  is no longer protected and userspace should take appropriate action
>   *	  (whatever that might be).
> + * CP_Content_Type:
> + *	This property is used by the userspace to configure the kernel with
> + *	upcoming stream's content type. Content Type of a stream is decided by
> + *	the owner of the stream, as Type 0 or Type 1.
> + *
> + *	The value of the property can be one the below:
> + *	  - DRM_MODE_CP_CONTENT_TYPE0 = 0
> + *		Type 0 streams can be transmitted on a link which is encrypted
> + *		with HDCP 1.4 or HDCP 2.2.
> + *	  - DRM_MODE_CP_CONTENT_TYPE1 = 1
> + *		Type 1 streams can be transmitted on a link which is encrypted
> + *		only with HDCP2.2.
> + *
> + *	Please note this content type is introduced at HDCP2.2 and used in its
> + *	authentication process.
> + *
> + *	Guideline for programming:
> + *	  - Property state can be changed only when "Content Protection state is
> + *		DRM_MODE_CONTENT_PROTECTION_UNDESIRED.

Why? We may need to force a modeset, but this looks like a silly restriction to expose this to userspace.

If userspace doesn't want a modeset, it can clear the DRM_MODE_ATOMIC_ALLOW_MODESET flag on atomic commit.

the intel_atomic_check() callback can force a modeset if required, and atomic core can fail if userspace didn't request it.

~Maarten

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Intel-gfx] [PATCH 02/10] drm/i915: Attach content type property
  2019-02-26  7:36 ` [PATCH 02/10] drm/i915: Attach " Ramalingam C
@ 2019-03-05 14:58   ` Maarten Lankhorst
  0 siblings, 0 replies; 15+ messages in thread
From: Maarten Lankhorst @ 2019-03-05 14:58 UTC (permalink / raw)
  To: Ramalingam C, intel-gfx, dri-devel, daniel.vetter, uma.shankar

Op 26-02-2019 om 08:36 schreef Ramalingam C:
> Attaches the content type property for HDCP2.2 capable connectors.
>
> Implements the update of content type from property and apply the
> restriction on HDCP version selection.
>
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c  | 21 +++++++++++++++------
>  drivers/gpu/drm/i915/intel_drv.h  |  2 +-
>  drivers/gpu/drm/i915/intel_hdcp.c | 18 +++++++++++++++---
>  3 files changed, 31 insertions(+), 10 deletions(-)
This should probably be the last patch, because we can only enable HDCP 2.2 with all patches merged?
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 1355be8dec3b..ffe7759a3f3a 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -3499,7 +3499,8 @@ static void intel_enable_ddi(struct intel_encoder *encoder,
>  	/* Enable hdcp if it's desired */
>  	if (conn_state->content_protection ==
>  	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> -		intel_hdcp_enable(to_intel_connector(conn_state->connector));
> +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> +				  (u8)conn_state->cp_content_type);
>  }
>  
>  static void intel_disable_ddi_dp(struct intel_encoder *encoder,
> @@ -3562,21 +3563,29 @@ static void intel_ddi_update_pipe_dp(struct intel_encoder *encoder,
>  	intel_panel_update_backlight(encoder, crtc_state, conn_state);
>  }
>  
> -static void intel_ddi_update_pipe(struct intel_encoder *encoder,
> +static void intel_ddi_update_hdcp(struct intel_encoder *encoder,
>  				  const struct intel_crtc_state *crtc_state,
>  				  const struct drm_connector_state *conn_state)
>  {
> -	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> -		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
> -
>  	if (conn_state->content_protection ==
>  	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> -		intel_hdcp_enable(to_intel_connector(conn_state->connector));
> +		intel_hdcp_enable(to_intel_connector(conn_state->connector),
> +				  (u8)conn_state->cp_content_type);
>  	else if (conn_state->content_protection ==
>  		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
>  		intel_hdcp_disable(to_intel_connector(conn_state->connector));
>  }
>  
> +static void intel_ddi_update_pipe(struct intel_encoder *encoder,
> +				  const struct intel_crtc_state *crtc_state,
> +				  const struct drm_connector_state *conn_state)
> +{
> +	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> +		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
> +
> +	intel_ddi_update_hdcp(encoder, crtc_state, conn_state);
> +}
> +
>  static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
>  					 const struct intel_crtc_state *pipe_config,
>  					 enum port port)
> diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
> index 81ec73e4a083..04cff672aead 100644
> --- a/drivers/gpu/drm/i915/intel_drv.h
> +++ b/drivers/gpu/drm/i915/intel_drv.h
> @@ -2151,7 +2151,7 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
>  			     struct drm_connector_state *new_state);
>  int intel_hdcp_init(struct intel_connector *connector,
>  		    const struct intel_hdcp_shim *hdcp_shim);
> -int intel_hdcp_enable(struct intel_connector *connector);
> +int intel_hdcp_enable(struct intel_connector *connector, u8 content_type);
>  int intel_hdcp_disable(struct intel_connector *connector);
>  bool is_hdcp_supported(struct drm_i915_private *dev_priv, enum port port);
>  bool intel_hdcp_capable(struct intel_connector *connector);
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> index 9ce09f67776d..ab25264a74a4 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -1782,6 +1782,12 @@ static void intel_hdcp2_init(struct intel_connector *connector)
>  		return;
>  	}
>  
> +	ret = drm_connector_attach_cp_content_type_property(&connector->base);
> +	if (ret) {
> +		kfree(hdcp->port_data.streams);
> +		return;
> +	}
> +
>  	hdcp->hdcp2_supported = true;
>  }
>  
> @@ -1811,7 +1817,7 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	return 0;
>  }
>  
> -int intel_hdcp_enable(struct intel_connector *connector)
> +int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
>  {
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	unsigned long check_link_interval = DRM_HDCP_CHECK_PERIOD_MS;
> @@ -1823,6 +1829,8 @@ int intel_hdcp_enable(struct intel_connector *connector)
>  	mutex_lock(&hdcp->mutex);
>  	WARN_ON(hdcp->value == DRM_MODE_CONTENT_PROTECTION_ENABLED);
>  
> +	hdcp->content_type = content_type;
> +
>  	/*
>  	 * Considering that HDCP2.2 is more secure than HDCP1.4, If the setup
>  	 * is capable of HDCP2.2, it is preferred to use HDCP2.2.
> @@ -1833,8 +1841,12 @@ int intel_hdcp_enable(struct intel_connector *connector)
>  			check_link_interval = DRM_HDCP2_CHECK_PERIOD_MS;
>  	}
>  
> -	/* When HDCP2.2 fails, HDCP1.4 will be attempted */
> -	if (ret && intel_hdcp_capable(connector)) {
> +	/*
> +	 * When HDCP2.2 fails and Content Type is not Type1, HDCP1.4 will
> +	 * be attempted.
> +	 */
> +	if (ret && intel_hdcp_capable(connector) &&
> +	    hdcp->content_type != DRM_MODE_CP_CONTENT_TYPE1) {
>  		ret = _intel_hdcp_enable(connector);
>  	}
>  


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH 01/10] drm: Add CP content type property
  2019-03-05 14:39   ` [Intel-gfx] " Maarten Lankhorst
@ 2019-03-05 19:00     ` C, Ramalingam
  0 siblings, 0 replies; 15+ messages in thread
From: C, Ramalingam @ 2019-03-05 19:00 UTC (permalink / raw)
  To: Maarten Lankhorst, intel-gfx, dri-devel, daniel.vetter, Shankar, Uma


> -----Original Message-----
> From: Maarten Lankhorst [mailto:maarten.lankhorst@linux.intel.com]
> Sent: Tuesday, March 5, 2019 8:09 PM
> To: C, Ramalingam <ramalingam.c@intel.com>; intel-gfx@lists.freedesktop.org;
> dri-devel@lists.freedesktop.org; daniel.vetter@ffwll.ch; Shankar, Uma
> <uma.shankar@intel.com>
> Subject: Re: [Intel-gfx] [PATCH 01/10] drm: Add CP content type property
> 
> Op 26-02-2019 om 08:36 schreef Ramalingam C:
> > This patch adds a DRM ENUM property to the selected connectors.
> > This property is used for pass the protected content's type from
> > userspace to kernel HDCP authentication.
> >
> > Type of the stream is decided by the protected content providers as
> > Type 0/1.
> >
> > 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 upon a content protection request with Type 1 as Content type from
> > userspace, Kernel will declare success only if the HDCP2.2
> > authentication is successful.
> >
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > ---
> >  drivers/gpu/drm/drm_atomic_uapi.c | 10 ++++++
> >  drivers/gpu/drm/drm_connector.c   | 64
> +++++++++++++++++++++++++++++++++++++++
> >  include/drm/drm_connector.h       | 15 +++++++++
> >  include/uapi/drm/drm_mode.h       |  4 +++
> >  4 files changed, 93 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c
> > b/drivers/gpu/drm/drm_atomic_uapi.c
> > index 4eb81f10bc54..5289486565ce 100644
> > --- a/drivers/gpu/drm/drm_atomic_uapi.c
> > +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> > @@ -746,6 +746,14 @@ static int
> drm_atomic_connector_set_property(struct drm_connector *connector,
> >  			return -EINVAL;
> >  		}
> >  		state->content_protection = val;
> > +	} else if (property == connector->cp_content_type_property) {
> > +		if (state->content_protection !=
> > +		    DRM_MODE_CONTENT_PROTECTION_UNDESIRED &&
> > +		    state->cp_content_type != val) {
> > +			DRM_DEBUG_KMS("Disable CP, then change Type\n");
> > +			return -EINVAL;
> > +		}
> > +		state->cp_content_type = val;
> 
> You can't add checks in atomic_set_property.

Thanks Maarten for the review.
I am afraid we have the similar check for content_protection, just above this.

> 
> Until we have the full state, we can't do any checks. This has to be done in the
> .atomic_check() callback.
> 
> Lets say atomic commit consists of the following:
> Set Content_Protection to desired.
> Set Content Type to Type 1.
> atomic setprop will fail
> 
> Plus the check itself is bogus. We should be able to change HDCP strictness
> without a modeset, the same way we enable and disable HDCP 1.4 with a
> fastset.

This is not modeset mandating, but the sequence of hdcp_disable->change Type->hdcp_enable from userspace.
Reason is we need to redo the hdcp authenticate with new Type value.

Alternate approach would be kernel performing disable and enable on Type change request from userspace.
For this we could disable hdcp at intel_hdcp_atomic_check and re-enable with new Type value at atomic_commit.

I thought it is better to leave the required preparation (disable and enable of hdcp) to userspace.
But if we prefer to push that into kernel also it is doable. Share your opinion please.

> 
> >  	} else if (property == connector->colorspace_property) {
> >  		state->colorspace = val;
> >  	} else if (property == config->writeback_fb_id_property) { @@ -822,6
> > +830,8 @@ drm_atomic_connector_get_property(struct drm_connector
> *connector,
> >  		*val = state->scaling_mode;
> >  	} else if (property == connector->content_protection_property) {
> >  		*val = state->content_protection;
> > +	} else if (property == connector->cp_content_type_property) {
> > +		*val = state->cp_content_type;
> >  	} else if (property == config->writeback_fb_id_property) {
> >  		/* Writeback framebuffer is one-shot, write and forget */
> >  		*val = 0;
> > diff --git a/drivers/gpu/drm/drm_connector.c
> > b/drivers/gpu/drm/drm_connector.c index 07d65a16c623..5d7738e1e977
> > 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -853,6 +853,13 @@ static const struct drm_prop_enum_list
> hdmi_colorspaces[] = {
> >  	{ DRM_MODE_COLORIMETRY_DCI_P3_RGB_THEATER, "DCI-
> P3_RGB_Theater" },
> > };
> >
> > +static struct drm_prop_enum_list drm_cp_content_type_enum_list[] = {
> > +	{ DRM_MODE_CP_CONTENT_TYPE0, "Type 0" },
> > +	{ DRM_MODE_CP_CONTENT_TYPE1, "Type 1" }, };
> > +
> > +DRM_ENUM_NAME_FN(drm_get_cp_content_type_name,
> > +drm_cp_content_type_enum_list)
> > +
> >  /**
> >   * DOC: standard connector properties
> >   *
> > @@ -958,6 +965,25 @@ static const struct drm_prop_enum_list
> hdmi_colorspaces[] = {
> >   *	  the value transitions from ENABLED to DESIRED. This signifies the link
> >   *	  is no longer protected and userspace should take appropriate action
> >   *	  (whatever that might be).
> > + * CP_Content_Type:
> > + *	This property is used by the userspace to configure the kernel with
> > + *	upcoming stream's content type. Content Type of a stream is decided by
> > + *	the owner of the stream, as Type 0 or Type 1.
> > + *
> > + *	The value of the property can be one the below:
> > + *	  - DRM_MODE_CP_CONTENT_TYPE0 = 0
> > + *		Type 0 streams can be transmitted on a link which is encrypted
> > + *		with HDCP 1.4 or HDCP 2.2.
> > + *	  - DRM_MODE_CP_CONTENT_TYPE1 = 1
> > + *		Type 1 streams can be transmitted on a link which is encrypted
> > + *		only with HDCP2.2.
> > + *
> > + *	Please note this content type is introduced at HDCP2.2 and used in its
> > + *	authentication process.
> > + *
> > + *	Guideline for programming:
> > + *	  - Property state can be changed only when "Content Protection state is
> > + *		DRM_MODE_CONTENT_PROTECTION_UNDESIRED.
> 
> Why? We may need to force a modeset, but this looks like a silly restriction to
> expose this to userspace.
> 
> If userspace doesn't want a modeset, it can clear the
> DRM_MODE_ATOMIC_ALLOW_MODESET flag on atomic commit.
> 
> the intel_atomic_check() callback can force a modeset if required, and atomic
> core can fail if userspace didn't request it.

As I have explained above this doesn't force modeset. Just expecting userspace to disable
hdcp before changing the Type value.

--Ram

> 
> ~Maarten

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-03-05 19:00 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-26  7:35 [PATCH 00/10] HDCP2.2 Phase II Ramalingam C
2019-02-26  7:36 ` [PATCH 01/10] drm: Add CP content type property Ramalingam C
2019-03-05 14:39   ` [Intel-gfx] " Maarten Lankhorst
2019-03-05 19:00     ` C, Ramalingam
2019-02-26  7:36 ` [PATCH 02/10] drm/i915: Attach " Ramalingam C
2019-03-05 14:58   ` [Intel-gfx] " Maarten Lankhorst
2019-02-26  7:36 ` [PATCH 03/10] drm: Add CP System Renewability Msg Property Ramalingam C
2019-02-26  7:36 ` [PATCH 04/10] drm/i915: Add HDCP SRM Blob parsing Ramalingam C
2019-02-26  7:36 ` [PATCH 05/10] drm/i915: Add revocation check on HDCP1.4 Ksvs Ramalingam C
2019-02-26  7:36 ` [PATCH 06/10] drm/i915: SRM parsing and revocation check for HDCP2 Ramalingam C
2019-02-26  7:36 ` [PATCH 07/10] drm: Add CP downstream_info property Ramalingam C
2019-02-26  7:36 ` [PATCH 08/10] drm/i915: Populate downstream info for HDCP1.4 Ramalingam C
2019-02-26  7:36 ` [PATCH 09/10] drm/i915: Populate downstream info for HDCP2.2 Ramalingam C
2019-02-26  7:36 ` [PATCH 10/10] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
2019-02-26  8:24 ` [PATCH 00/10] HDCP2.2 Phase II Daniel Vetter

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).