All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v5 00/12] HDCP2.2 Phase II
@ 2019-04-18  8:57 Ramalingam C
  2019-04-18  8:57 ` [PATCH v5 01/12] drm: move content protection property to mode_config Ramalingam C
                   ` (17 more replies)
  0 siblings, 18 replies; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:57 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

HDCP2.2 phase-II introduces below features:
	Addition of two connector properties
		HDCP Content Type
		HDCP Topology
	Addition of binary sysfs "hdcp_srm" at drm subsystem
	Parsing for HDCP1.4 and 2.2 SRM table
	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.
	Uevent for HDCP state change.
	Dedicated file for hdcp in drm.

HDCP 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.

HDCP Topology:
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.

hdcp_srm: write only binary sysfs 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.

Daniel has suggested about moving the SRM node implementation into DRM core.
Still dome more clarification is required. Once that is done another
respin on SRM patches are expected.

v5:
  srm is read from the /lib/firmware/display_hdcp_srm.bin [danvet]
  small fix at hdcp state update to userspace.
 
Series can be cloned from github
https://github.com/ramalingampc2008/drm-tip.git hdcp2_2_p2_v5

Test-with: <20190418084842.5422-2-ramalingam.c@intel.com>

Ramalingam C (12):
  drm: move content protection property to mode_config
  drm/i915: debugfs: HDCP2.2 capability read
  drm: Add Content protection type property
  drm/i915: Attach content type property
  drm: revocation check at drm subsystem
  drm/i915: SRM revocation check for HDCP1.4 and 2.2
  drm/hdcp: gathering hdcp related code into drm_hdcp.c
  drm: uevent for connector status change
  drm/hdcp: update content protection property with uevent
  drm/i915: update the hdcp state with uevent
  drm: Add CP downstream_info property
  drm/i915: Populate downstream info for HDCP

 drivers/gpu/drm/Makefile            |   2 +-
 drivers/gpu/drm/drm_atomic_uapi.c   |  11 +-
 drivers/gpu/drm/drm_connector.c     |  80 +++--
 drivers/gpu/drm/drm_hdcp.c          | 498 ++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_internal.h      |   4 +
 drivers/gpu/drm/drm_sysfs.c         |  33 ++
 drivers/gpu/drm/i915/i915_debugfs.c |  13 +-
 drivers/gpu/drm/i915/intel_ddi.c    |  38 ++-
 drivers/gpu/drm/i915/intel_drv.h    |   2 +
 drivers/gpu/drm/i915/intel_hdcp.c   | 177 +++++++---
 drivers/gpu/drm/i915/intel_hdcp.h   |   3 +-
 include/drm/drm_connector.h         |  21 +-
 include/drm/drm_hdcp.h              |  48 +++
 include/drm/drm_mode_config.h       |  18 +
 include/drm/drm_sysfs.h             |   5 +-
 include/uapi/drm/drm_mode.h         |  41 +++
 16 files changed, 894 insertions(+), 100 deletions(-)
 create mode 100644 drivers/gpu/drm/drm_hdcp.c

-- 
2.19.1

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

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

* [PATCH v5 01/12] drm: move content protection property to mode_config
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
@ 2019-04-18  8:57 ` Ramalingam C
  2019-04-23  7:38   ` Daniel Vetter
  2019-04-18  8:57 ` [PATCH v5 02/12] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:57 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

Content protection property is created once and stored in
drm_mode_config. And attached to all HDCP capable connectors.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/drm_atomic_uapi.c |  4 ++--
 drivers/gpu/drm/drm_connector.c   | 13 +++++++------
 include/drm/drm_connector.h       |  6 ------
 include/drm/drm_mode_config.h     |  6 ++++++
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index ea797d4c82ee..002dcede7915 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -727,7 +727,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 		state->content_type = val;
 	} else if (property == connector->scaling_mode_property) {
 		state->scaling_mode = val;
-	} else if (property == connector->content_protection_property) {
+	} else if (property == config->content_protection_property) {
 		if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
 			DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
 			return -EINVAL;
@@ -807,7 +807,7 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->colorspace;
 	} else if (property == connector->scaling_mode_property) {
 		*val = state->scaling_mode;
-	} else if (property == connector->content_protection_property) {
+	} else if (property == config->content_protection_property) {
 		*val = state->content_protection;
 	} else if (property == config->writeback_fb_id_property) {
 		/* Writeback framebuffer is one-shot, write and forget */
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 2355124849db..7c0eda9cca60 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -1534,18 +1534,19 @@ int drm_connector_attach_content_protection_property(
 		struct drm_connector *connector)
 {
 	struct drm_device *dev = connector->dev;
-	struct drm_property *prop;
+	struct drm_property *prop =
+			dev->mode_config.content_protection_property;
 
-	prop = drm_property_create_enum(dev, 0, "Content Protection",
-					drm_cp_enum_list,
-					ARRAY_SIZE(drm_cp_enum_list));
+	if (!prop)
+		prop = drm_property_create_enum(dev, 0, "Content Protection",
+						drm_cp_enum_list,
+						ARRAY_SIZE(drm_cp_enum_list));
 	if (!prop)
 		return -ENOMEM;
 
 	drm_object_attach_property(&connector->base, prop,
 				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
-
-	connector->content_protection_property = prop;
+	dev->mode_config.content_protection_property = prop;
 
 	return 0;
 }
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 02a131202add..5e41942e5679 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1061,12 +1061,6 @@ struct drm_connector {
 	 */
 	struct drm_property *vrr_capable_property;
 
-	/**
-	 * @content_protection_property: DRM ENUM property for content
-	 * protection. See drm_connector_attach_content_protection_property().
-	 */
-	struct drm_property *content_protection_property;
-
 	/**
 	 * @colorspace_property: Connector property to set the suitable
 	 * colorspace supported by the sink.
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 7f60e8eb269a..5764ee3c7453 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -836,6 +836,12 @@ struct drm_mode_config {
 	 */
 	struct drm_property *writeback_out_fence_ptr_property;
 
+	/**
+	 * @content_protection_property: DRM ENUM property for content
+	 * protection. See drm_connector_attach_content_protection_property().
+	 */
+	struct drm_property *content_protection_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
-- 
2.19.1

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

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

* [PATCH v5 02/12] drm/i915: debugfs: HDCP2.2 capability read
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
  2019-04-18  8:57 ` [PATCH v5 01/12] drm: move content protection property to mode_config Ramalingam C
@ 2019-04-18  8:57 ` Ramalingam C
  2019-04-18  8:57 ` [PATCH v5 03/12] drm: Add Content protection type property Ramalingam C
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:57 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

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.

v2:
  Rebased.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_debugfs.c | 13 +++++++++++--
 drivers/gpu/drm/i915/intel_hdcp.c   |  2 +-
 drivers/gpu/drm/i915/intel_hdcp.h   |  1 +
 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 5823ffb17821..f0b977ad6b97 100644
--- a/drivers/gpu/drm/i915/i915_debugfs.c
+++ b/drivers/gpu/drm/i915/i915_debugfs.c
@@ -4757,6 +4757,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;
@@ -4767,8 +4768,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_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 99b007169c49..440fef448feb 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -78,7 +78,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);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.h b/drivers/gpu/drm/i915/intel_hdcp.h
index a75f25f09d39..be8da85c866a 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.h
+++ b/drivers/gpu/drm/i915/intel_hdcp.h
@@ -25,6 +25,7 @@ int intel_hdcp_enable(struct intel_connector *connector);
 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);
-- 
2.19.1

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

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

* [PATCH v5 03/12] drm: Add Content protection type property
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
  2019-04-18  8:57 ` [PATCH v5 01/12] drm: move content protection property to mode_config Ramalingam C
  2019-04-18  8:57 ` [PATCH v5 02/12] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
@ 2019-04-18  8:57 ` Ramalingam C
  2019-04-23  7:44   ` Daniel Vetter
  2019-04-18  8:57 ` [PATCH v5 04/12] drm/i915: Attach content " Ramalingam C
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:57 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

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

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

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

v2:
  cp_content_type is replaced with content_protection_type [daniel]
  check at atomic_set_property is removed [Maarten]
v3:
  %s/content_protection_type/hdcp_content_type [Pekka]
v4:
  property is created for the first requested connector and then reused.
	[Danvet]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/drm_atomic_uapi.c |  4 +++
 drivers/gpu/drm/drm_connector.c   | 53 ++++++++++++++++++++++++++++++-
 drivers/gpu/drm/i915/intel_hdcp.c |  4 ++-
 include/drm/drm_connector.h       |  9 +++++-
 include/drm/drm_mode_config.h     |  6 ++++
 include/uapi/drm/drm_mode.h       |  4 +++
 6 files changed, 77 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 002dcede7915..0b0747869963 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -733,6 +733,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
 			return -EINVAL;
 		}
 		state->content_protection = val;
+	} else if (property == config->hdcp_content_type_property) {
+		state->hdcp_content_type = val;
 	} else if (property == connector->colorspace_property) {
 		state->colorspace = val;
 	} else if (property == config->writeback_fb_id_property) {
@@ -809,6 +811,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->scaling_mode;
 	} else if (property == config->content_protection_property) {
 		*val = state->content_protection;
+	} else if (property == config->hdcp_content_type_property) {
+		*val = state->hdcp_content_type;
 	} else if (property == config->writeback_fb_id_property) {
 		/* Writeback framebuffer is one-shot, write and forget */
 		*val = 0;
diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 7c0eda9cca60..03907d13ef66 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -857,6 +857,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_hdcp_content_type_enum_list[] = {
+	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
+	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
+		 drm_hdcp_content_type_enum_list)
+
 /**
  * DOC: standard connector properties
  *
@@ -962,6 +969,23 @@ 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).
+ * HDCP 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 HDCP Type0 or HDCP Type1.
+ *
+ *	The value of the property can be one the below:
+ *	  - DRM_MODE_HDCP_CONTENT_TYPE0 = 0
+ *		HDCP Type0 streams can be transmitted on a link which is
+ *		encrypted with HDCP 1.4 or HDCP 2.2.
+ *	  - DRM_MODE_HDCP_CONTENT_TYPE1 = 1
+ *		HDCP Type1 streams can be transmitted on a link which is
+ *		encrypted only with HDCP 2.2.
+ *
+ *	Please note this content type is introduced at HDCP 2.2 and used in its
+ *	authentication process. If content type is changed when
+ *	content_protection is not UNDESIRED, then kernel will disable the HDCP
+ *	and re-enable with new type in the same atomic commit
  *
  * max bpc:
  *	This range property is used by userspace to limit the bit depth. When
@@ -1520,18 +1544,29 @@ EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
  * property
  *
  * @connector: connector to attach CP property on.
+ * @hdcp_content_type: is HDCP Content Type property needed for connector
  *
  * This is used to add support for content protection on select connectors.
  * Content Protection is intentionally vague to allow for different underlying
  * technologies, however it is most implemented by HDCP.
  *
+ * When hdcp_content_type is true enum property called HDCP Content Type is
+ * created (if it is not already) and attached to the connector.
+ *
+ * This property is used for sending the protected content's stream type
+ * from userspace to kernel on selected connectors. Protected content provider
+ * will decide their type of their content and declare the same to kernel.
+ *
+ * Content type will be used during the HDCP 2.2 authentication.
+ * Content type will be set to &drm_connector_state.hdcp_content_type.
+ *
  * The content protection will be set to &drm_connector_state.content_protection
  *
  * Returns:
  * Zero on success, negative errno on failure.
  */
 int drm_connector_attach_content_protection_property(
-		struct drm_connector *connector)
+		struct drm_connector *connector, bool hdcp_content_type)
 {
 	struct drm_device *dev = connector->dev;
 	struct drm_property *prop =
@@ -1548,6 +1583,22 @@ int drm_connector_attach_content_protection_property(
 				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
 	dev->mode_config.content_protection_property = prop;
 
+	if (!hdcp_content_type)
+		return 0;
+
+	prop = dev->mode_config.hdcp_content_type_property;
+	if (!prop)
+		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+					drm_hdcp_content_type_enum_list,
+					ARRAY_SIZE(
+					drm_hdcp_content_type_enum_list));
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop,
+				   DRM_MODE_HDCP_CONTENT_TYPE0);
+	dev->mode_config.hdcp_content_type_property = prop;
+
 	return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 440fef448feb..a61391d374e8 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1798,7 +1798,9 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (!shim)
 		return -EINVAL;
 
-	ret = drm_connector_attach_content_protection_property(&connector->base);
+	ret =
+	drm_connector_attach_content_protection_property(&connector->base,
+							 false);
 	if (ret)
 		return ret;
 
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 5e41942e5679..2d2c2d5e7681 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -556,6 +556,12 @@ struct drm_connector_state {
 	 */
 	unsigned int content_type;
 
+	/**
+	 * @hdcp_content_type: Connector property to pass the type of
+	 * protected content. This is most commonly used for HDCP.
+	 */
+	unsigned int hdcp_content_type;
+
 	/**
 	 * @scaling_mode: Connector property to control the
 	 * upscaling, mostly used for built-in panels.
@@ -1326,6 +1332,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_hdcp_content_type_name(int val);
 
 int drm_mode_create_dvi_i_properties(struct drm_device *dev);
 int drm_mode_create_tv_margin_properties(struct drm_device *dev);
@@ -1340,7 +1347,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
 int drm_connector_attach_vrr_capable_property(
 		struct drm_connector *connector);
 int drm_connector_attach_content_protection_property(
-		struct drm_connector *connector);
+		struct drm_connector *connector, bool hdcp_content_type);
 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/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 5764ee3c7453..b359b5b71eb9 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -842,6 +842,12 @@ struct drm_mode_config {
 	 */
 	struct drm_property *content_protection_property;
 
+	/**
+	 * @hdcp_content_type_property: DRM ENUM property for type of
+	 * Protected Content.
+	 */
+	struct drm_property *hdcp_content_type_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 83cd1636b9be..8ac03351fdee 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -209,6 +209,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_HDCP_CONTENT_TYPE0		0
+#define DRM_MODE_HDCP_CONTENT_TYPE1		1
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
2.19.1

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

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

* [PATCH v5 04/12] drm/i915: Attach content type property
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (2 preceding siblings ...)
  2019-04-18  8:57 ` [PATCH v5 03/12] drm: Add Content protection type property Ramalingam C
@ 2019-04-18  8:57 ` Ramalingam C
  2019-04-23  8:11   ` Daniel Vetter
  2019-04-18  8:57 ` [PATCH v5 05/12] drm: revocation check at drm subsystem Ramalingam C
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:57 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

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.

v2:
  s/cp_content_type/content_protection_type [daniel]
  disable at hdcp_atomic_check to avoid check at atomic_set_property
	[Maarten]
v3:
  s/content_protection_type/hdcp_content_type [Pekka]
v4:
  hdcp disable incase of type change is moved into commit [daniel].

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

diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index 24f9106efcc6..dd9bea840937 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -3476,7 +3476,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->hdcp_content_type);
 }
 
 static void intel_disable_ddi_dp(struct intel_encoder *encoder,
@@ -3545,15 +3546,44 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
 				  const struct intel_crtc_state *crtc_state,
 				  const struct drm_connector_state *conn_state)
 {
+	struct intel_connector *connector =
+				to_intel_connector(conn_state->connector);
+	struct intel_hdcp *hdcp = &connector->hdcp;
+	bool  re_enable_hdcp = false;
+	int ret = -EINVAL;
+
 	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
 		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
 
+	/*
+	 * During the HDCP encryption session if Type change is requested,
+	 * disable the HDCP and reenable it with new TYPE value.
+	 */
 	if (conn_state->content_protection ==
-	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
-		intel_hdcp_enable(to_intel_connector(conn_state->connector));
+	    DRM_MODE_CONTENT_PROTECTION_ENABLED &&
+	    conn_state->hdcp_content_type != hdcp->content_type) {
+		intel_hdcp_disable(to_intel_connector(conn_state->connector));
+		re_enable_hdcp = true;
+	}
+
+	if (conn_state->content_protection ==
+	    DRM_MODE_CONTENT_PROTECTION_DESIRED || re_enable_hdcp)
+		ret = intel_hdcp_enable(connector,
+					(u8)conn_state->hdcp_content_type);
 	else if (conn_state->content_protection ==
 		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
-		intel_hdcp_disable(to_intel_connector(conn_state->connector));
+		intel_hdcp_disable(connector);
+
+	/*
+	 * During Type change handling re-enabling of the HDCP failed. Hence
+	 * changes state as ENABLED->DESIRED.
+	 */
+	if (ret && re_enable_hdcp) {
+		mutex_lock(&hdcp->mutex);
+		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
+		schedule_work(&hdcp->prop_work);
+		mutex_unlock(&hdcp->mutex);
+	}
 }
 
 static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index a61391d374e8..772974697b5a 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -1717,14 +1717,15 @@ static const struct component_ops i915_hdcp_component_ops = {
 	.unbind = i915_hdcp_component_unbind,
 };
 
-static inline int initialize_hdcp_port_data(struct intel_connector *connector)
+static inline int initialize_hdcp_port_data(struct intel_connector *connector,
+					    const struct intel_hdcp_shim *shim)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	struct hdcp_port_data *data = &hdcp->port_data;
 
 	data->port = connector->encoder->port;
 	data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
-	data->protocol = (u8)hdcp->shim->protocol;
+	data->protocol = (u8)shim->protocol;
 
 	data->k = 1;
 	if (!data->streams)
@@ -1774,12 +1775,13 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
 	}
 }
 
-static void intel_hdcp2_init(struct intel_connector *connector)
+static void intel_hdcp2_init(struct intel_connector *connector,
+			     const struct intel_hdcp_shim *shim)
 {
 	struct intel_hdcp *hdcp = &connector->hdcp;
 	int ret;
 
-	ret = initialize_hdcp_port_data(connector);
+	ret = initialize_hdcp_port_data(connector, shim);
 	if (ret) {
 		DRM_DEBUG_KMS("Mei hdcp data init failed\n");
 		return;
@@ -1798,25 +1800,28 @@ int intel_hdcp_init(struct intel_connector *connector,
 	if (!shim)
 		return -EINVAL;
 
+	if (is_hdcp2_supported(dev_priv))
+		intel_hdcp2_init(connector, shim);
+
 	ret =
 	drm_connector_attach_content_protection_property(&connector->base,
-							 false);
-	if (ret)
+							 hdcp->hdcp2_supported);
+	if (ret) {
+		hdcp->hdcp2_supported = false;
+		kfree(hdcp->port_data.streams);
 		return ret;
+	}
 
 	hdcp->shim = shim;
 	mutex_init(&hdcp->mutex);
 	INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work);
 	INIT_WORK(&hdcp->prop_work, intel_hdcp_prop_work);
-
-	if (is_hdcp2_supported(dev_priv))
-		intel_hdcp2_init(connector);
 	init_waitqueue_head(&hdcp->cp_irq_queue);
 
 	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;
@@ -1827,6 +1832,7 @@ 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
@@ -1838,8 +1844,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_HDCP_CONTENT_TYPE1) {
 		ret = _intel_hdcp_enable(connector);
 	}
 
@@ -1921,12 +1931,15 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
 
 	/*
 	 * Nothing to do if the state didn't change, or HDCP was activated since
-	 * the last commit
+	 * the last commit. And also no change in hdcp content type.
 	 */
 	if (old_cp == new_cp ||
 	    (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
-	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED))
-		return;
+	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) {
+		if (old_state->hdcp_content_type ==
+				new_state->hdcp_content_type)
+			return;
+	}
 
 	crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
 						   new_state->crtc);
diff --git a/drivers/gpu/drm/i915/intel_hdcp.h b/drivers/gpu/drm/i915/intel_hdcp.h
index be8da85c866a..13555b054930 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.h
+++ b/drivers/gpu/drm/i915/intel_hdcp.h
@@ -21,7 +21,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);
-- 
2.19.1

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

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

* [PATCH v5 05/12] drm: revocation check at drm subsystem
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (3 preceding siblings ...)
  2019-04-18  8:57 ` [PATCH v5 04/12] drm/i915: Attach content " Ramalingam C
@ 2019-04-18  8:57 ` Ramalingam C
  2019-04-29  7:26   ` Daniel Vetter
  2019-04-18  8:57 ` [PATCH v5 06/12] drm/i915: SRM revocation check for HDCP1.4 and 2.2 Ramalingam C
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:57 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

On every hdcp revocation check request SRM is read from fw file
/lib/firmware/display_hdcp_srm.bin

SRM table is parsed and stored at drm_hdcp.c, with functions exported
for the services for revocation check from drivers (which
implements the HDCP authentication)

This patch handles the HDCP1.4 and 2.2 versions of SRM table.

v2:
  moved the uAPI to request_firmware_direct() [Daniel]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
---
 drivers/gpu/drm/Makefile       |   2 +-
 drivers/gpu/drm/drm_hdcp.c     | 336 +++++++++++++++++++++++++++++++++
 drivers/gpu/drm/drm_internal.h |   4 +
 drivers/gpu/drm/drm_sysfs.c    |   2 +
 include/drm/drm_hdcp.h         |  36 ++++
 5 files changed, 379 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/drm_hdcp.c

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 3d0c75cd687c..fe8400af2426 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -19,7 +19,7 @@ drm-y       :=	drm_auth.o drm_bufs.o drm_cache.o \
 		drm_plane.o drm_color_mgmt.o drm_print.o \
 		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
 		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
-		drm_atomic_uapi.o
+		drm_atomic_uapi.o drm_hdcp.o
 
 drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
 drm-$(CONFIG_DRM_VM) += drm_vm.o
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
new file mode 100644
index 000000000000..78b043c8195e
--- /dev/null
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -0,0 +1,336 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2019 Intel Corporation.
+ *
+ * Authors:
+ * Ramalingam C <ramalingam.c@intel.com>
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gfp.h>
+#include <linux/export.h>
+#include <linux/slab.h>
+#include <linux/firmware.h>
+
+#include <drm/drm_hdcp.h>
+#include <drm/drm_sysfs.h>
+#include <drm/drm_print.h>
+#include <drm/drm_device.h>
+
+struct hdcp_srm {
+	u8 *srm_buf;
+	size_t received_srm_sz;
+	u32 revocated_ksv_cnt;
+	u8 *revocated_ksv_list;
+
+	/* Mutex to protect above struct member */
+	struct mutex mutex;
+} *srm_data;
+
+static inline void drm_hdcp_print_ksv(const char *ksv)
+{
+	DRM_DEBUG("\t%#04x, %#04x, %#04x, %#04x, %#04x\n", *ksv & 0xff,
+		  *(ksv + 1) & 0xff, *(ksv + 2) & 0xff, *(ksv + 3) & 0xff,
+		  *(ksv + 4) & 0xff);
+}
+
+static u32 drm_hdcp_get_revocated_ksv_count(const char *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 drm_hdcp_get_revocated_ksvs(const char *buf, u8 *revocated_ksv_list,
+				       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("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
+			  vrl_ksv_cnt);
+		memcpy(revocated_ksv_list, buf, vrl_ksv_sz);
+
+		ksv_count += vrl_ksv_cnt;
+		revocated_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 drm_hdcp_parse_hdcp1_srm(const char *buf, size_t count)
+{
+	struct hdcp_srm_header *header;
+	u32 vrl_length, ksv_count;
+
+	if (count < (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 *)buf;
+	mutex_lock(&srm_data->mutex);
+	DRM_DEBUG("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");
+		mutex_unlock(&srm_data->mutex);
+		return -EINVAL;
+	}
+
+	buf = buf + sizeof(*header);
+	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));
+	if (count < (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");
+		mutex_unlock(&srm_data->mutex);
+		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_ERROR("No vrl found\n");
+		mutex_unlock(&srm_data->mutex);
+		return -EINVAL;
+	}
+
+	buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
+	ksv_count = drm_hdcp_get_revocated_ksv_count(buf, vrl_length);
+	if (!ksv_count) {
+		DRM_DEBUG("Revocated KSV count is 0\n");
+		mutex_unlock(&srm_data->mutex);
+		return count;
+	}
+
+	kfree(srm_data->revocated_ksv_list);
+	srm_data->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
+					       GFP_KERNEL);
+	if (!srm_data->revocated_ksv_list) {
+		DRM_ERROR("Out of Memory\n");
+		mutex_unlock(&srm_data->mutex);
+		return -ENOMEM;
+	}
+
+	if (drm_hdcp_get_revocated_ksvs(buf, srm_data->revocated_ksv_list,
+					vrl_length) != ksv_count) {
+		srm_data->revocated_ksv_cnt = 0;
+		kfree(srm_data->revocated_ksv_list);
+		mutex_unlock(&srm_data->mutex);
+		return -EINVAL;
+	}
+
+	srm_data->revocated_ksv_cnt = ksv_count;
+	mutex_unlock(&srm_data->mutex);
+	return count;
+}
+
+static int drm_hdcp_parse_hdcp2_srm(const char *buf, size_t count)
+{
+	struct hdcp2_srm_header *header;
+	u32 vrl_length, ksv_count, ksv_sz;
+
+	mutex_lock(&srm_data->mutex);
+	if (count < (sizeof(struct hdcp2_srm_header) +
+	    DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) {
+		DRM_ERROR("Invalid blob length\n");
+		mutex_unlock(&srm_data->mutex);
+		return -EINVAL;
+	}
+
+	header = (struct hdcp2_srm_header *)buf;
+	DRM_DEBUG("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);
+
+	if (header->spec_indicator.reserved)
+		return -EINVAL;
+
+	buf = buf + sizeof(*header);
+	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));
+
+	if (count < (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");
+		mutex_unlock(&srm_data->mutex);
+		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");
+		mutex_unlock(&srm_data->mutex);
+		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) {
+		DRM_DEBUG("Revocated KSV count is 0\n");
+		mutex_unlock(&srm_data->mutex);
+		return count;
+	}
+
+	kfree(srm_data->revocated_ksv_list);
+	srm_data->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
+					       GFP_KERNEL);
+	if (!srm_data->revocated_ksv_list) {
+		DRM_ERROR("Out of Memory\n");
+		mutex_unlock(&srm_data->mutex);
+		return -ENOMEM;
+	}
+
+	ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
+	buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
+
+	DRM_DEBUG("Revoked KSVs: %d\n", ksv_count);
+	memcpy(srm_data->revocated_ksv_list, buf, ksv_sz);
+
+	srm_data->revocated_ksv_cnt = ksv_count;
+	mutex_unlock(&srm_data->mutex);
+	return count;
+}
+
+static inline bool is_srm_version_hdcp1(const char *buf)
+{
+	return ((u8)*buf) == DRM_HDCP_1_4_SRM_ID << 4;
+}
+
+static inline bool is_srm_version_hdcp2(const char *buf)
+{
+	return ((u8)*buf) == (DRM_HDCP_2_SRM_ID << 4 |
+			     DRM_HDCP_2_INDICATOR);
+}
+
+static ssize_t drm_hdcp_srm_update(const char *buf, size_t count)
+{
+	if (is_srm_version_hdcp1(buf))
+		return (ssize_t)drm_hdcp_parse_hdcp1_srm(buf, count);
+	else if (is_srm_version_hdcp2(buf))
+		return (ssize_t)drm_hdcp_parse_hdcp2_srm(buf, count);
+
+	return (ssize_t)-EINVAL;
+}
+
+void drm_hdcp_request_srm(struct drm_device *drm_dev)
+{
+	char fw_name[36] = "display_hdcp_srm.bin";
+	const struct firmware *fw;
+
+	int ret;
+
+	ret = request_firmware_direct(&fw, (const char *)fw_name,
+				      drm_dev->dev);
+	if (ret < 0)
+		goto exit;
+
+	if (fw->size && fw->data)
+		drm_hdcp_srm_update((const char *)fw->data, fw->size);
+
+exit:
+	release_firmware(fw);
+}
+
+/* Check if any of the KSV is revocated by DCP LLC through SRM table */
+bool drm_hdcp_ksvs_revocated(struct drm_device *drm_dev, u8 *ksvs,
+			     u32 ksv_count)
+{
+	u32 rev_ksv_cnt, cnt, i, j;
+	u8 *rev_ksv_list;
+
+	if (!srm_data)
+		return false;
+
+	drm_hdcp_request_srm(drm_dev);
+
+	mutex_lock(&srm_data->mutex);
+	rev_ksv_cnt = srm_data->revocated_ksv_cnt;
+	rev_ksv_list = srm_data->revocated_ksv_list;
+
+	/* If the Revocated ksv list is empty */
+	if (!rev_ksv_cnt || !rev_ksv_list) {
+		mutex_unlock(&srm_data->mutex);
+		return false;
+	}
+
+	for  (cnt = 0; cnt < ksv_count; cnt++) {
+		rev_ksv_list = srm_data->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("Revocated KSV is ");
+					drm_hdcp_print_ksv(ksvs);
+					mutex_unlock(&srm_data->mutex);
+					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;
+	}
+	mutex_unlock(&srm_data->mutex);
+	return false;
+}
+EXPORT_SYMBOL_GPL(drm_hdcp_ksvs_revocated);
+
+int drm_setup_hdcp_srm(struct class *drm_class)
+{
+	srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
+	if (!srm_data)
+		return -ENOMEM;
+
+	srm_data->srm_buf = kcalloc(DRM_HDCP_SRM_GEN1_MAX_BYTES,
+				    sizeof(u8), GFP_KERNEL);
+	if (!srm_data->srm_buf) {
+		kfree(srm_data);
+		return -ENOMEM;
+	}
+	mutex_init(&srm_data->mutex);
+
+	return 0;
+}
+
+void drm_teardown_hdcp_srm(struct class *drm_class)
+{
+	if (srm_data) {
+		kfree(srm_data->srm_buf);
+		kfree(srm_data->revocated_ksv_list);
+		kfree(srm_data);
+	}
+}
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index d9a483a5fce0..ef3180443870 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -199,3 +199,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
 void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
 				const struct drm_framebuffer *fb);
 int drm_framebuffer_debugfs_init(struct drm_minor *minor);
+
+/* drm_hdcp.c */
+int drm_setup_hdcp_srm(struct class *drm_class);
+void drm_teardown_hdcp_srm(struct class *drm_class);
diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index ecb7b33002bb..18b1ac442997 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -78,6 +78,7 @@ int drm_sysfs_init(void)
 	}
 
 	drm_class->devnode = drm_devnode;
+	drm_setup_hdcp_srm(drm_class);
 	return 0;
 }
 
@@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)
 {
 	if (IS_ERR_OR_NULL(drm_class))
 		return;
+	drm_teardown_hdcp_srm(drm_class);
 	class_remove_file(drm_class, &class_attr_version.attr);
 	class_destroy(drm_class);
 	drm_class = NULL;
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index f243408ecf26..ff2bcfc1ecef 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -265,4 +265,40 @@ 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_SRM_GEN1_MAX_BYTES		(5 * 1024)
+#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;
+
+#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)
+
+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;
+
+struct drm_device;
+
+bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
 #endif
-- 
2.19.1

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

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

* [PATCH v5 06/12] drm/i915: SRM revocation check for HDCP1.4 and 2.2
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (4 preceding siblings ...)
  2019-04-18  8:57 ` [PATCH v5 05/12] drm: revocation check at drm subsystem Ramalingam C
@ 2019-04-18  8:57 ` Ramalingam C
  2019-04-29  7:28   ` Daniel Vetter
  2019-04-18  8:58 ` [PATCH v5 07/12] drm/hdcp: gathering hdcp related code into drm_hdcp.c Ramalingam C
                   ` (11 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:57 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

DRM HDCP SRM revocation check services are used from I915 for HDCP1.4
and 2.2 revocation check during the respective authentication flow.

v2:
  Rebased.

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

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 772974697b5a..de634f3fbd1b 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -492,9 +492,11 @@ 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_connector *connector)
 {
+	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
+	const struct intel_hdcp_shim *shim = connector->hdcp.shim;
+	struct drm_device *dev = connector->base.dev;
 	u8 bstatus[2], num_downstream, *ksv_fifo;
 	int ret, i, tries = 3;
 
@@ -533,6 +535,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
 	if (ret)
 		goto err;
 
+	if (drm_hdcp_ksvs_revocated(dev, 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.
@@ -559,9 +566,12 @@ 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;
+	struct drm_device *dev = connector->base.dev;
+	const struct intel_hdcp_shim *shim = hdcp->shim;
 	struct drm_i915_private *dev_priv;
 	enum port port;
 	unsigned long r0_prime_gen_start;
@@ -627,6 +637,11 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
 	if (ret < 0)
 		return ret;
 
+	if (drm_hdcp_ksvs_revocated(dev, 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]);
 
@@ -700,7 +715,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(connector);
 
 	DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n");
 	return 0;
@@ -763,7 +778,7 @@ 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;
 			return 0;
@@ -779,12 +794,6 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
 	return ret;
 }
 
-static inline
-struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
-{
-	return container_of(hdcp, struct intel_connector, hdcp);
-}
-
 /* Implements Part 3 of the HDCP authorization procedure */
 static int intel_hdcp_check_link(struct intel_connector *connector)
 {
@@ -845,6 +854,12 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
 	return ret;
 }
 
+static inline
+struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
+{
+	return container_of(hdcp, struct intel_connector, hdcp);
+}
+
 static void intel_hdcp_prop_work(struct work_struct *work)
 {
 	struct intel_hdcp *hdcp = container_of(work, struct intel_hdcp,
@@ -1162,6 +1177,7 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
 {
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
+	struct drm_device *dev = connector->base.dev;
 	union {
 		struct hdcp2_ake_init ake_init;
 		struct hdcp2_ake_send_cert send_cert;
@@ -1196,6 +1212,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 (drm_hdcp_ksvs_revocated(dev,
+				    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.
@@ -1348,13 +1370,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 {
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	struct intel_hdcp *hdcp = &connector->hdcp;
+	struct drm_device *dev = connector->base.dev;
 	union {
 		struct hdcp2_rep_send_receiverid_list recvid_list;
 		struct hdcp2_rep_send_ack rep_ack;
 	} msgs;
 	const struct intel_hdcp_shim *shim = hdcp->shim;
+	u32 seq_num_v, device_cnt;
 	u8 *rx_info;
-	u32 seq_num_v;
 	int ret;
 
 	ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_REP_SEND_RECVID_LIST,
@@ -1379,6 +1402,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 (drm_hdcp_ksvs_revocated(dev, 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);
-- 
2.19.1

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

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

* [PATCH v5 07/12] drm/hdcp: gathering hdcp related code into drm_hdcp.c
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (5 preceding siblings ...)
  2019-04-18  8:57 ` [PATCH v5 06/12] drm/i915: SRM revocation check for HDCP1.4 and 2.2 Ramalingam C
@ 2019-04-18  8:58 ` Ramalingam C
  2019-04-29  7:31   ` Daniel Vetter
  2019-04-18  8:58 ` [PATCH v5 08/12] drm: uevent for connector status change Ramalingam C
                   ` (10 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:58 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

Considering the significant size of hdcp related code in drm, all
hdcp related codes are moved into separate file called drm_hdcp.c.

v2:
  Rebased.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
Suggested-by: Daniel Vetter <daniel@ffwll.ch>
---
 drivers/gpu/drm/drm_connector.c | 78 -------------------------------
 drivers/gpu/drm/drm_hdcp.c      | 81 +++++++++++++++++++++++++++++++++
 include/drm/drm_connector.h     |  2 -
 include/drm/drm_hdcp.h          |  3 ++
 4 files changed, 84 insertions(+), 80 deletions(-)

diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
index 03907d13ef66..436cf8e764cc 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -823,13 +823,6 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
 DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
 		 drm_tv_subconnector_enum_list)
 
-static struct drm_prop_enum_list drm_cp_enum_list[] = {
-	{ DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
-	{ DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
-	{ DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
-};
-DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
-
 static const struct drm_prop_enum_list hdmi_colorspaces[] = {
 	/* For Default case, driver will set the colorspace */
 	{ DRM_MODE_COLORIMETRY_DEFAULT, "Default" },
@@ -857,13 +850,6 @@ 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_hdcp_content_type_enum_list[] = {
-	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
-	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
-};
-DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
-		 drm_hdcp_content_type_enum_list)
-
 /**
  * DOC: standard connector properties
  *
@@ -1539,70 +1525,6 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
 }
 EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
 
-/**
- * drm_connector_attach_content_protection_property - attach content protection
- * property
- *
- * @connector: connector to attach CP property on.
- * @hdcp_content_type: is HDCP Content Type property needed for connector
- *
- * This is used to add support for content protection on select connectors.
- * Content Protection is intentionally vague to allow for different underlying
- * technologies, however it is most implemented by HDCP.
- *
- * When hdcp_content_type is true enum property called HDCP Content Type is
- * created (if it is not already) and attached to the connector.
- *
- * This property is used for sending the protected content's stream type
- * from userspace to kernel on selected connectors. Protected content provider
- * will decide their type of their content and declare the same to kernel.
- *
- * Content type will be used during the HDCP 2.2 authentication.
- * Content type will be set to &drm_connector_state.hdcp_content_type.
- *
- * The content protection will be set to &drm_connector_state.content_protection
- *
- * Returns:
- * Zero on success, negative errno on failure.
- */
-int drm_connector_attach_content_protection_property(
-		struct drm_connector *connector, bool hdcp_content_type)
-{
-	struct drm_device *dev = connector->dev;
-	struct drm_property *prop =
-			dev->mode_config.content_protection_property;
-
-	if (!prop)
-		prop = drm_property_create_enum(dev, 0, "Content Protection",
-						drm_cp_enum_list,
-						ARRAY_SIZE(drm_cp_enum_list));
-	if (!prop)
-		return -ENOMEM;
-
-	drm_object_attach_property(&connector->base, prop,
-				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
-	dev->mode_config.content_protection_property = prop;
-
-	if (!hdcp_content_type)
-		return 0;
-
-	prop = dev->mode_config.hdcp_content_type_property;
-	if (!prop)
-		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
-					drm_hdcp_content_type_enum_list,
-					ARRAY_SIZE(
-					drm_hdcp_content_type_enum_list));
-	if (!prop)
-		return -ENOMEM;
-
-	drm_object_attach_property(&connector->base, prop,
-				   DRM_MODE_HDCP_CONTENT_TYPE0);
-	dev->mode_config.hdcp_content_type_property = prop;
-
-	return 0;
-}
-EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
-
 /**
  * drm_mode_create_aspect_ratio_property - create aspect ratio property
  * @dev: DRM device
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 78b043c8195e..a0960507e4ff 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -17,6 +17,9 @@
 #include <drm/drm_sysfs.h>
 #include <drm/drm_print.h>
 #include <drm/drm_device.h>
+#include <drm/drm_property.h>
+#include <drm/drm_mode_object.h>
+#include <drm/drm_connector.h>
 
 struct hdcp_srm {
 	u8 *srm_buf;
@@ -334,3 +337,81 @@ void drm_teardown_hdcp_srm(struct class *drm_class)
 		kfree(srm_data);
 	}
 }
+
+static struct drm_prop_enum_list drm_cp_enum_list[] = {
+	{ DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
+	{ DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
+	{ DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
+};
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
+
+static struct drm_prop_enum_list drm_hdcp_content_type_enum_list[] = {
+	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
+	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
+		 drm_hdcp_content_type_enum_list)
+
+/**
+ * drm_connector_attach_content_protection_property - attach content protection
+ * property
+ *
+ * @connector: connector to attach CP property on.
+ * @hdcp_content_type: is HDCP Content Type property needed for connector
+ *
+ * This is used to add support for content protection on select connectors.
+ * Content Protection is intentionally vague to allow for different underlying
+ * technologies, however it is most implemented by HDCP.
+ *
+ * When hdcp_content_type is true enum property called HDCP Content Type is
+ * created (if it is not already) and attached to the connector.
+ *
+ * This property is used for sending the protected content's stream type
+ * from userspace to kernel on selected connectors. Protected content provider
+ * will decide their type of their content and declare the same to kernel.
+ *
+ * Content type will be used during the HDCP 2.2 authentication.
+ * Content type will be set to &drm_connector_state.hdcp_content_type.
+ *
+ * The content protection will be set to &drm_connector_state.content_protection
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_content_protection_property(
+		struct drm_connector *connector, bool hdcp_content_type)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop =
+			dev->mode_config.content_protection_property;
+
+	if (!prop)
+		prop = drm_property_create_enum(dev, 0, "Content Protection",
+						drm_cp_enum_list,
+						ARRAY_SIZE(drm_cp_enum_list));
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop,
+				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
+	dev->mode_config.content_protection_property = prop;
+
+	if (!hdcp_content_type)
+		return 0;
+
+	prop = dev->mode_config.hdcp_content_type_property;
+	if (!prop)
+		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+					drm_hdcp_content_type_enum_list,
+					ARRAY_SIZE(
+					drm_hdcp_content_type_enum_list));
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop,
+				   DRM_MODE_HDCP_CONTENT_TYPE0);
+	dev->mode_config.hdcp_content_type_property = prop;
+
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 2d2c2d5e7681..9e2f1a9de2a0 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1346,8 +1346,6 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
 					       u32 scaling_mode_mask);
 int drm_connector_attach_vrr_capable_property(
 		struct drm_connector *connector);
-int drm_connector_attach_content_protection_property(
-		struct drm_connector *connector, bool hdcp_content_type);
 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/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index ff2bcfc1ecef..145c81ba1e09 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -299,6 +299,9 @@ struct hdcp2_srm_header {
 } __packed;
 
 struct drm_device;
+struct drm_connector;
 
 bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
+int drm_connector_attach_content_protection_property(
+		struct drm_connector *connector, bool hdcp_content_type);
 #endif
-- 
2.19.1

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

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

* [PATCH v5 08/12] drm: uevent for connector status change
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (6 preceding siblings ...)
  2019-04-18  8:58 ` [PATCH v5 07/12] drm/hdcp: gathering hdcp related code into drm_hdcp.c Ramalingam C
@ 2019-04-18  8:58 ` Ramalingam C
  2019-04-29  7:33   ` Daniel Vetter
  2019-04-18  8:58 ` [PATCH v5 09/12] drm/hdcp: update content protection property with uevent Ramalingam C
                   ` (9 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:58 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

DRM API for generating uevent for a status changes of connector's
property.

This uevent will have following details related to the status change:

  HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
v2:
  Minor fixes at KDoc comments [Daniel]

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/drm_sysfs.c | 31 +++++++++++++++++++++++++++++++
 include/drm/drm_sysfs.h     |  5 ++++-
 2 files changed, 35 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
index 18b1ac442997..e8f1fd73677f 100644
--- a/drivers/gpu/drm/drm_sysfs.c
+++ b/drivers/gpu/drm/drm_sysfs.c
@@ -320,6 +320,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
  * Send a uevent for the DRM device specified by @dev.  Currently we only
  * set HOTPLUG=1 in the uevent environment, but this could be expanded to
  * deal with other types of events.
+ *
+ * Any new uapi should be using the drm_sysfs_connector_status_event()
+ * for uevents on connector status change.
  */
 void drm_sysfs_hotplug_event(struct drm_device *dev)
 {
@@ -332,6 +335,34 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_sysfs_hotplug_event);
 
+/**
+ * drm_sysfs_connector_status_event - generate a DRM uevent for connector
+ * property status change
+ * @connector: connector on which property status changed
+ * @property: connector property whoes status changed.
+ *
+ * Send a uevent for the DRM device specified by @dev.  Currently we
+ * set HOTPLUG=1 and connector id along with the attached property id
+ * related to the status change.
+ */
+void drm_sysfs_connector_status_event(struct drm_connector *connector,
+				      struct drm_property *property)
+{
+	struct drm_device *dev = connector->dev;
+	char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
+	char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
+
+	snprintf(conn_id, ARRAY_SIZE(conn_id),
+		 "CONNECTOR=%u", connector->base.id);
+	snprintf(prop_id, ARRAY_SIZE(prop_id),
+		 "PROPERTY=%u", property->base.id);
+
+	DRM_DEBUG("generating connector status event\n");
+
+	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
+}
+EXPORT_SYMBOL(drm_sysfs_connector_status_event);
+
 static void drm_sysfs_release(struct device *dev)
 {
 	kfree(dev);
diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
index 4f311e836cdc..d454ef617b2c 100644
--- a/include/drm/drm_sysfs.h
+++ b/include/drm/drm_sysfs.h
@@ -4,10 +4,13 @@
 
 struct drm_device;
 struct device;
+struct drm_connector;
+struct drm_property;
 
 int drm_class_device_register(struct device *dev);
 void drm_class_device_unregister(struct device *dev);
 
 void drm_sysfs_hotplug_event(struct drm_device *dev);
-
+void drm_sysfs_connector_status_event(struct drm_connector *connector,
+				      struct drm_property *property);
 #endif
-- 
2.19.1

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

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

* [PATCH v5 09/12] drm/hdcp: update content protection property with uevent
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (7 preceding siblings ...)
  2019-04-18  8:58 ` [PATCH v5 08/12] drm: uevent for connector status change Ramalingam C
@ 2019-04-18  8:58 ` Ramalingam C
  2019-04-29  7:35   ` Daniel Vetter
  2019-04-18  8:58 ` [PATCH v5 10/12] drm/i915: update the hdcp state " Ramalingam C
                   ` (8 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:58 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

drm function is defined and exported to update a connector's
content protection property state and to generate a uevent along
with it.

v2:
  Update only when state is different from old one.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/drm_hdcp.c | 16 ++++++++++++++++
 include/drm/drm_hdcp.h     |  2 ++
 2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index a0960507e4ff..5640c4e744fe 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -415,3 +415,19 @@ int drm_connector_attach_content_protection_property(
 	return 0;
 }
 EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
+
+void drm_hdcp_update_content_protection(struct drm_connector *connector,
+					u64 val)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_connector_state *state = connector->state;
+
+	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
+	if (state->content_protection == val)
+		return;
+
+	state->content_protection = val;
+	drm_sysfs_connector_status_event(connector,
+				 dev->mode_config.content_protection_property);
+}
+EXPORT_SYMBOL(drm_hdcp_update_content_protection);
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 145c81ba1e09..9457c7ec0d37 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -304,4 +304,6 @@ struct drm_connector;
 bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
 int drm_connector_attach_content_protection_property(
 		struct drm_connector *connector, bool hdcp_content_type);
+void drm_hdcp_update_content_protection(struct drm_connector *connector,
+					u64 val);
 #endif
-- 
2.19.1

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

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

* [PATCH v5 10/12] drm/i915: update the hdcp state with uevent
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (8 preceding siblings ...)
  2019-04-18  8:58 ` [PATCH v5 09/12] drm/hdcp: update content protection property with uevent Ramalingam C
@ 2019-04-18  8:58 ` Ramalingam C
  2019-04-29  7:35   ` Daniel Vetter
  2019-04-18  8:58 ` [PATCH v5 11/12] drm: Add CP downstream_info property Ramalingam C
                   ` (7 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:58 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

drm function to update the content protection property state and to
generate a uevent is invoked from the intel hdcp property work.

Hence whenever kernel changes the property state, userspace will be
updated with a uevent.

v2:
  state update is moved into drm function [daniel]

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

diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index de634f3fbd1b..84ac23ea75af 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -866,7 +866,6 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 					       prop_work);
 	struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
 	struct drm_device *dev = connector->base.dev;
-	struct drm_connector_state *state;
 
 	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
 	mutex_lock(&hdcp->mutex);
@@ -876,10 +875,9 @@ static void intel_hdcp_prop_work(struct work_struct *work)
 	 * those to UNDESIRED is handled by core. If value == UNDESIRED,
 	 * we're running just after hdcp has been disabled, so just exit
 	 */
-	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
-		state = connector->base.state;
-		state->content_protection = hdcp->value;
-	}
+	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
+		drm_hdcp_update_content_protection(&connector->base,
+						   hdcp->value);
 
 	mutex_unlock(&hdcp->mutex);
 	drm_modeset_unlock(&dev->mode_config.connection_mutex);
-- 
2.19.1

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

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

* [PATCH v5 11/12] drm: Add CP downstream_info property
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (9 preceding siblings ...)
  2019-04-18  8:58 ` [PATCH v5 10/12] drm/i915: update the hdcp state " Ramalingam C
@ 2019-04-18  8:58 ` Ramalingam C
  2019-04-29  7:38   ` Daniel Vetter
  2019-04-18  8:58 ` [PATCH v5 12/12] drm/i915: Populate downstream info for HDCP Ramalingam C
                   ` (6 subsequent siblings)
  17 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:58 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

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

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

In case userspace configures this platform as repeater, then this
information is needed for the authentication with upstream HDCP
transmitter.

v2:
  s/cp_downstream/content_protection_downstream [daniel]
v3:
  s/content_protection_downstream/hdcp_topology [daniel]
v4:
  hdcp_topology_info struct is added with explicit padding [Daniel]
v5:
  Rebased.

Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
---
 drivers/gpu/drm/drm_atomic_uapi.c |  3 ++
 drivers/gpu/drm/drm_connector.c   | 20 ++++++++++
 drivers/gpu/drm/drm_hdcp.c        | 65 +++++++++++++++++++++++++++++++
 include/drm/drm_connector.h       |  6 +++
 include/drm/drm_hdcp.h            |  6 +++
 include/drm/drm_mode_config.h     |  6 +++
 include/uapi/drm/drm_mode.h       | 37 ++++++++++++++++++
 7 files changed, 143 insertions(+)

diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
index 0b0747869963..1c9e1ab0d536 100644
--- a/drivers/gpu/drm/drm_atomic_uapi.c
+++ b/drivers/gpu/drm/drm_atomic_uapi.c
@@ -813,6 +813,9 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
 		*val = state->content_protection;
 	} else if (property == config->hdcp_content_type_property) {
 		*val = state->hdcp_content_type;
+	} else if (property == config->hdcp_topology_property) {
+		*val = connector->hdcp_topology_blob_ptr ?
+			connector->hdcp_topology_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 436cf8e764cc..033ced774d37 100644
--- a/drivers/gpu/drm/drm_connector.c
+++ b/drivers/gpu/drm/drm_connector.c
@@ -246,6 +246,7 @@ int drm_connector_init(struct drm_device *dev,
 	mutex_init(&connector->mutex);
 	connector->edid_blob_ptr = NULL;
 	connector->tile_blob_ptr = NULL;
+	connector->hdcp_topology_blob_ptr = NULL;
 	connector->status = connector_status_unknown;
 	connector->display_info.panel_orientation =
 		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
@@ -972,6 +973,25 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
  *	authentication process. If content type is changed when
  *	content_protection is not UNDESIRED, then kernel will disable the HDCP
  *	and re-enable with new type in the same atomic commit
+ * HDCP Topology:
+ *	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
diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
index 5640c4e744fe..c0d3fc93fc50 100644
--- a/drivers/gpu/drm/drm_hdcp.c
+++ b/drivers/gpu/drm/drm_hdcp.c
@@ -431,3 +431,68 @@ void drm_hdcp_update_content_protection(struct drm_connector *connector,
 				 dev->mode_config.content_protection_property);
 }
 EXPORT_SYMBOL(drm_hdcp_update_content_protection);
+
+/**
+ * drm_connector_attach_hdcp_topology_property - attach hdcp topology property
+ *
+ * @connector: connector to attach hdcp topology property with.
+ *
+ * This is used to add support for hdcp topology support 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 blob_id of the hdcp topology info will be set to
+ * &drm_connector_state.hdcp_topology
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int drm_connector_attach_hdcp_topology_property(struct drm_connector *connector)
+{
+	struct drm_device *dev = connector->dev;
+	struct drm_property *prop = dev->mode_config.hdcp_topology_property;
+
+	if (!prop)
+		prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
+					   DRM_MODE_PROP_IMMUTABLE,
+					   "HDCP Topology", 0);
+	if (!prop)
+		return -ENOMEM;
+
+	drm_object_attach_property(&connector->base, prop, 0);
+	dev->mode_config.hdcp_topology_property = prop;
+	return 0;
+}
+EXPORT_SYMBOL(drm_connector_attach_hdcp_topology_property);
+
+/**
+ * drm_connector_update_hdcp_topology_property - update the hdcp topology
+ * property of a connector
+ * @connector: drm connector, the topology is associated to
+ * @hdcp_topology_info: new content for the blob of hdcp_topology_property
+ *
+ * This function creates a new blob modeset object and assigns its id to the
+ * connector's hdcp_topology_property.
+ *
+ * Returns:
+ * Zero on success, negative errno on failure.
+ */
+int
+drm_connector_update_hdcp_topology_property(struct drm_connector *connector,
+					const struct hdcp_topology_info *info)
+{
+	struct drm_device *dev = connector->dev;
+	int ret;
+
+	if (!info)
+		return -EINVAL;
+
+	ret = drm_property_replace_global_blob(dev,
+			&connector->hdcp_topology_blob_ptr,
+			sizeof(struct hdcp_topology_info),
+			info, &connector->base,
+			dev->mode_config.hdcp_topology_property);
+	return ret;
+}
+EXPORT_SYMBOL(drm_connector_update_hdcp_topology_property);
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index 9e2f1a9de2a0..180f8f4d4526 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -1050,6 +1050,12 @@ struct drm_connector {
 	/** @properties: property tracking for this connector */
 	struct drm_object_properties properties;
 
+	/**
+	 * @hdcp_topology_blob_ptr: DRM BLOB pointer for hdcp downstream
+	 * topology information.
+	 */
+	struct drm_property_blob *hdcp_topology_blob_ptr;
+
 	/**
 	 * @scaling_mode_property: Optional atomic property to control the
 	 * upscaling. See drm_connector_attach_content_protection_property().
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 9457c7ec0d37..011f35e121a5 100644
--- a/include/drm/drm_hdcp.h
+++ b/include/drm/drm_hdcp.h
@@ -300,10 +300,16 @@ struct hdcp2_srm_header {
 
 struct drm_device;
 struct drm_connector;
+struct hdcp_topology_info;
 
 bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
 int drm_connector_attach_content_protection_property(
 		struct drm_connector *connector, bool hdcp_content_type);
 void drm_hdcp_update_content_protection(struct drm_connector *connector,
 					u64 val);
+int drm_connector_attach_hdcp_topology_property(
+				struct drm_connector *connector);
+int drm_connector_update_hdcp_topology_property(
+				struct drm_connector *connector,
+				const struct hdcp_topology_info *info);
 #endif
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index b359b5b71eb9..4349b614fa15 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -848,6 +848,12 @@ struct drm_mode_config {
 	 */
 	struct drm_property *hdcp_content_type_property;
 
+	/**
+	 * @hdcp_topology_property: DRM BLOB property for hdcp downstream
+	 * topology information.
+	 */
+	struct drm_property *hdcp_topology_property;
+
 	/* dumb ioctl parameters */
 	uint32_t preferred_depth, prefer_shadow;
 
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 8ac03351fdee..9d7cdfab4962 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -213,6 +213,43 @@ extern "C" {
 #define DRM_MODE_HDCP_CONTENT_TYPE0		0
 #define DRM_MODE_HDCP_CONTENT_TYPE1		1
 
+#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 hdcp_topology_info {
+	/* Version of HDCP authenticated (1.4/2.2) */
+	__u32 ver_in_force;
+
+	/* Applicable only for HDCP2.2 */
+	__u32 content_type;
+
+	/* KSV of immediate HDCP Sink. In Little-Endian Format. */
+	__u8 bksv[DRM_MODE_HDCP_KSV_LEN];
+
+	/* Whether Immediate HDCP sink is a repeater? */
+	__u8 is_repeater;
+
+	/* Depth received from immediate downstream repeater */
+	__u8 depth;
+	__u8 pad1;
+
+	/* 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.
+	 */
+	__u8 ksv_list[DRM_MODE_HDCP_KSV_LEN * DRM_MODE_HDCP_MAX_DEVICE_CNT];
+	__u8 pad2[5];
+} __packed;
+
 struct drm_mode_modeinfo {
 	__u32 clock;
 	__u16 hdisplay;
-- 
2.19.1

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

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

* [PATCH v5 12/12] drm/i915: Populate downstream info for HDCP
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (10 preceding siblings ...)
  2019-04-18  8:58 ` [PATCH v5 11/12] drm: Add CP downstream_info property Ramalingam C
@ 2019-04-18  8:58 ` Ramalingam C
  2019-04-18 10:35 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev6) Patchwork
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 33+ messages in thread
From: Ramalingam C @ 2019-04-18  8:58 UTC (permalink / raw)
  To: intel-gfx, dri-devel, daniel, gwan-gyeong.mun

Implements drm blob property content_protection_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
content_protection_downstream_info property.

v2:
  %s/cp_downstream/content_protection_downstream [daniel]
v3:
  %s/content_protection_downstream/hdcp_topology [daniel]
v4:
  Rebased.
v5:
  Rebased.

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

diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
index a38b9cff5cd0..b998479d89e7 100644
--- a/drivers/gpu/drm/i915/intel_drv.h
+++ b/drivers/gpu/drm/i915/intel_drv.h
@@ -485,6 +485,8 @@ struct intel_hdcp {
 	wait_queue_head_t cp_irq_queue;
 	atomic_t cp_irq_count;
 	int cp_irq_count_cached;
+
+	struct hdcp_topology_info *topology_info;
 };
 
 struct intel_connector {
diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
index 84ac23ea75af..1c75df1ccaf5 100644
--- a/drivers/gpu/drm/i915/intel_hdcp.c
+++ b/drivers/gpu/drm/i915/intel_hdcp.c
@@ -496,6 +496,7 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector)
 {
 	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
 	const struct intel_hdcp_shim *shim = connector->hdcp.shim;
+	struct intel_hdcp *hdcp = &connector->hdcp;
 	struct drm_device *dev = connector->base.dev;
 	u8 bstatus[2], num_downstream, *ksv_fifo;
 	int ret, i, tries = 3;
@@ -527,6 +528,9 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector)
 	if (num_downstream == 0)
 		return -EINVAL;
 
+	hdcp->topology_info->device_count = num_downstream;
+	hdcp->topology_info->depth = DRM_HDCP_DEPTH(bstatus[1]);
+
 	ksv_fifo = kcalloc(DRM_HDCP_KSV_LEN, num_downstream, GFP_KERNEL);
 	if (!ksv_fifo)
 		return -ENOMEM;
@@ -540,6 +544,8 @@ int intel_hdcp_auth_downstream(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	memcpy(hdcp->topology_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.
@@ -642,15 +648,20 @@ static int intel_hdcp_auth(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	hdcp->topology_info->ver_in_force = DRM_MODE_HDCP14_IN_FORCE;
+	memcpy(hdcp->topology_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->topology_info->is_repeater = true;
+	}
 
 	ret = shim->toggle_signalling(intel_dig_port, true);
 	if (ret)
@@ -747,13 +758,18 @@ static int _intel_hdcp_disable(struct intel_connector *connector)
 		return ret;
 	}
 
+	memset(hdcp->topology_info, 0, sizeof(struct hdcp_topology_info));
+
+	if (drm_connector_update_hdcp_topology_property(&connector->base,
+						connector->hdcp.topology_info))
+		DRM_ERROR("Downstream_info update failed.\n");
+
 	DRM_DEBUG_KMS("HDCP is disabled\n");
 	return 0;
 }
 
 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;
 
@@ -780,7 +796,11 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
 	for (i = 0; i < tries; i++) {
 		ret = intel_hdcp_auth(connector);
 		if (!ret) {
-			hdcp->hdcp_encrypted = true;
+			connector->hdcp.hdcp_encrypted = true;
+			if (drm_connector_update_hdcp_topology_property(
+					&connector->base,
+					connector->hdcp.topology_info))
+				DRM_ERROR("Downstream_info update failed.\n");
 			return 0;
 		}
 
@@ -1216,6 +1236,12 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	hdcp->topology_info->ver_in_force = DRM_MODE_HDCP22_IN_FORCE;
+	hdcp->topology_info->content_type = hdcp->content_type;
+	memcpy(hdcp->topology_info->bksv, msgs.send_cert.cert_rx.receiver_id,
+	       HDCP_2_2_RECEIVER_ID_LEN);
+	hdcp->topology_info->is_repeater = hdcp->is_repeater;
+
 	/*
 	 * Here msgs.no_stored_km will hold msgs corresponding to the km
 	 * stored also.
@@ -1408,6 +1434,11 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
 		return -EPERM;
 	}
 
+	hdcp->topology_info->device_count = device_cnt;
+	hdcp->topology_info->depth = HDCP_2_2_DEPTH(rx_info[0]);
+	memcpy(hdcp->topology_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);
@@ -1594,6 +1625,12 @@ 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->topology_info, 0,
+		       sizeof(struct hdcp_topology_info));
+		drm_connector_update_hdcp_topology_property(&connector->base,
+							  hdcp->topology_info);
+
 		return ret;
 	}
 
@@ -1601,12 +1638,16 @@ static int _intel_hdcp2_enable(struct intel_connector *connector)
 		      connector->base.name, connector->base.base.id,
 		      hdcp->content_type);
 
+	drm_connector_update_hdcp_topology_property(&connector->base,
+						    hdcp->topology_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",
@@ -1617,8 +1658,11 @@ 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->topology_info, 0, sizeof(struct hdcp_topology_info));
+	drm_connector_update_hdcp_topology_property(&connector->base,
+						    hdcp->topology_info);
 	return ret;
 }
 
@@ -1835,10 +1879,17 @@ int intel_hdcp_init(struct intel_connector *connector,
 	ret =
 	drm_connector_attach_content_protection_property(&connector->base,
 							 hdcp->hdcp2_supported);
-	if (ret) {
-		hdcp->hdcp2_supported = false;
-		kfree(hdcp->port_data.streams);
-		return ret;
+	if (ret)
+		goto err_exit;
+
+	ret = drm_connector_attach_hdcp_topology_property(&connector->base);
+	if (ret)
+		goto err_exit;
+
+	hdcp->topology_info = kzalloc(sizeof(*hdcp->topology_info), GFP_KERNEL);
+	if (!hdcp->topology_info) {
+		ret = -ENOMEM;
+		goto err_exit;
 	}
 
 	hdcp->shim = shim;
@@ -1848,6 +1899,12 @@ int intel_hdcp_init(struct intel_connector *connector,
 	init_waitqueue_head(&hdcp->cp_irq_queue);
 
 	return 0;
+
+err_exit:
+	hdcp->hdcp2_supported = false;
+	kfree(hdcp->port_data.streams);
+
+	return ret;
 }
 
 int intel_hdcp_enable(struct intel_connector *connector, u8 content_type)
diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
index 011f35e121a5..34836d42675b 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))
 
-- 
2.19.1

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

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

* ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev6)
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (11 preceding siblings ...)
  2019-04-18  8:58 ` [PATCH v5 12/12] drm/i915: Populate downstream info for HDCP Ramalingam C
@ 2019-04-18 10:35 ` Patchwork
  2019-04-18 10:43 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2019-04-18 10:35 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev6)
URL   : https://patchwork.freedesktop.org/series/57232/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
84f4dac3e9b8 drm: move content protection property to mode_config
3c1930de9fbf drm/i915: debugfs: HDCP2.2 capability read
1a264b2ef997 drm: Add Content protection type property
-:63: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#63: FILE: drivers/gpu/drm/drm_connector.c:864:
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,

-:134: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#134: FILE: drivers/gpu/drm/drm_connector.c:1592:
+		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+					drm_hdcp_content_type_enum_list,

-:135: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#135: FILE: drivers/gpu/drm/drm_connector.c:1593:
+					ARRAY_SIZE(

total: 0 errors, 0 warnings, 3 checks, 163 lines checked
8c0a8787c1b7 drm/i915: Attach content type property
e689efd90f92 drm: revocation check at drm subsystem
-:35: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#35: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 405 lines checked
4b42fc1b52f3 drm/i915: SRM revocation check for HDCP1.4 and 2.2
1d5083ebcc50 drm/hdcp: gathering hdcp related code into drm_hdcp.c
-:142: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#142: FILE: drivers/gpu/drm/drm_hdcp.c:346:
+};
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)

-:148: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#148: FILE: drivers/gpu/drm/drm_hdcp.c:352:
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,

-:177: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#177: FILE: drivers/gpu/drm/drm_hdcp.c:381:
+int drm_connector_attach_content_protection_property(

-:201: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#201: FILE: drivers/gpu/drm/drm_hdcp.c:405:
+		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+					drm_hdcp_content_type_enum_list,

-:202: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#202: FILE: drivers/gpu/drm/drm_hdcp.c:406:
+					ARRAY_SIZE(

-:238: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#238: FILE: include/drm/drm_hdcp.h:305:
+int drm_connector_attach_content_protection_property(

total: 0 errors, 0 warnings, 6 checks, 203 lines checked
121d9d86da15 drm: uevent for connector status change
697d2bd18789 drm/hdcp: update content protection property with uevent
-:36: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#36: FILE: drivers/gpu/drm/drm_hdcp.c:431:
+	drm_sysfs_connector_status_event(connector,
+				 dev->mode_config.content_protection_property);

total: 0 errors, 0 warnings, 1 checks, 25 lines checked
1be1de17135f drm/i915: update the hdcp state with uevent
8bffda7e3b53 drm: Add CP downstream_info property
-:137: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#137: FILE: drivers/gpu/drm/drm_hdcp.c:483:
+drm_connector_update_hdcp_topology_property(struct drm_connector *connector,
+					const struct hdcp_topology_info *info)

-:146: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#146: FILE: drivers/gpu/drm/drm_hdcp.c:492:
+	ret = drm_property_replace_global_blob(dev,
+			&connector->hdcp_topology_blob_ptr,

-:185: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#185: FILE: include/drm/drm_hdcp.h:310:
+int drm_connector_attach_hdcp_topology_property(

-:187: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#187: FILE: include/drm/drm_hdcp.h:312:
+int drm_connector_update_hdcp_topology_property(

total: 0 errors, 0 warnings, 4 checks, 192 lines checked
fb121266b6b7 drm/i915: Populate downstream info for HDCP
-:98: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#98: FILE: drivers/gpu/drm/i915/intel_hdcp.c:764:
+	if (drm_connector_update_hdcp_topology_property(&connector->base,
+						connector->hdcp.topology_info))

-:117: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#117: FILE: drivers/gpu/drm/i915/intel_hdcp.c:800:
+			if (drm_connector_update_hdcp_topology_property(

-:157: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#157: FILE: drivers/gpu/drm/i915/intel_hdcp.c:1632:
+		drm_connector_update_hdcp_topology_property(&connector->base,
+							  hdcp->topology_info);

total: 0 errors, 0 warnings, 3 checks, 187 lines checked

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

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

* ✗ Fi.CI.SPARSE: warning for HDCP2.2 Phase II (rev6)
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (12 preceding siblings ...)
  2019-04-18 10:35 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev6) Patchwork
@ 2019-04-18 10:43 ` Patchwork
  2019-04-18 11:17 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev7) Patchwork
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2019-04-18 10:43 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev6)
URL   : https://patchwork.freedesktop.org/series/57232/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm: move content protection property to mode_config
Okay!

Commit: drm/i915: debugfs: HDCP2.2 capability read
Okay!

Commit: drm: Add Content protection type property
Okay!

Commit: drm/i915: Attach content type property
Okay!

Commit: drm: revocation check at drm subsystem
+drivers/gpu/drm/drm_hdcp.c:247:6: warning: symbol 'drm_hdcp_request_srm' was not declared. Should it be static?
+drivers/gpu/drm/drm_hdcp.c:29:3: warning: symbol 'srm_data' was not declared. Should it be static?
+drivers/gpu/drm/drm_hdcp.c:329:6: warning: symbol 'drm_teardown_hdcp_srm' was not declared. Should it be static?
+./include/linux/slab.h:666:13: error: undefined identifier '__builtin_mul_overflow'
+./include/linux/slab.h:666:13: warning: call with no type!

Commit: drm/i915: SRM revocation check for HDCP1.4 and 2.2
Okay!

Commit: drm/hdcp: gathering hdcp related code into drm_hdcp.c
Okay!

Commit: drm: uevent for connector status change
Okay!

Commit: drm/hdcp: update content protection property with uevent
Okay!

Commit: drm/i915: update the hdcp state with uevent
Okay!

Commit: drm: Add CP downstream_info property
Okay!

Commit: drm/i915: Populate downstream info for HDCP
Okay!

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

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

* ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev7)
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (13 preceding siblings ...)
  2019-04-18 10:43 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2019-04-18 11:17 ` Patchwork
  2019-04-18 11:25 ` ✗ Fi.CI.SPARSE: " Patchwork
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2019-04-18 11:17 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev7)
URL   : https://patchwork.freedesktop.org/series/57232/
State : warning

== Summary ==

$ dim checkpatch origin/drm-tip
4c5fcb196eb7 drm: move content protection property to mode_config
49dbee2b7e34 drm/i915: debugfs: HDCP2.2 capability read
f394967e1c97 drm: Add Content protection type property
-:63: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#63: FILE: drivers/gpu/drm/drm_connector.c:864:
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,

-:134: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#134: FILE: drivers/gpu/drm/drm_connector.c:1592:
+		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+					drm_hdcp_content_type_enum_list,

-:135: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#135: FILE: drivers/gpu/drm/drm_connector.c:1593:
+					ARRAY_SIZE(

total: 0 errors, 0 warnings, 3 checks, 163 lines checked
d8db5b5b9147 drm/i915: Attach content type property
1c19c4f8620b drm: revocation check at drm subsystem
-:35: WARNING:FILE_PATH_CHANGES: added, moved or deleted file(s), does MAINTAINERS need updating?
#35: 
new file mode 100644

total: 0 errors, 1 warnings, 0 checks, 405 lines checked
30d4513a2b5a drm/i915: SRM revocation check for HDCP1.4 and 2.2
f509333fff7e drm/hdcp: gathering hdcp related code into drm_hdcp.c
-:142: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#142: FILE: drivers/gpu/drm/drm_hdcp.c:346:
+};
+DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)

-:148: CHECK:LINE_SPACING: Please use a blank line after function/struct/union/enum declarations
#148: FILE: drivers/gpu/drm/drm_hdcp.c:352:
+};
+DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,

-:177: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#177: FILE: drivers/gpu/drm/drm_hdcp.c:381:
+int drm_connector_attach_content_protection_property(

-:201: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#201: FILE: drivers/gpu/drm/drm_hdcp.c:405:
+		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
+					drm_hdcp_content_type_enum_list,

-:202: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#202: FILE: drivers/gpu/drm/drm_hdcp.c:406:
+					ARRAY_SIZE(

-:238: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#238: FILE: include/drm/drm_hdcp.h:305:
+int drm_connector_attach_content_protection_property(

total: 0 errors, 0 warnings, 6 checks, 203 lines checked
df0f1eb5d4cd drm: uevent for connector status change
a3e81ac66413 drm/hdcp: update content protection property with uevent
-:36: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#36: FILE: drivers/gpu/drm/drm_hdcp.c:431:
+	drm_sysfs_connector_status_event(connector,
+				 dev->mode_config.content_protection_property);

total: 0 errors, 0 warnings, 1 checks, 25 lines checked
5c248b12771b drm/i915: update the hdcp state with uevent
115e48f3f606 drm: Add CP downstream_info property
-:137: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#137: FILE: drivers/gpu/drm/drm_hdcp.c:483:
+drm_connector_update_hdcp_topology_property(struct drm_connector *connector,
+					const struct hdcp_topology_info *info)

-:146: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#146: FILE: drivers/gpu/drm/drm_hdcp.c:492:
+	ret = drm_property_replace_global_blob(dev,
+			&connector->hdcp_topology_blob_ptr,

-:185: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#185: FILE: include/drm/drm_hdcp.h:310:
+int drm_connector_attach_hdcp_topology_property(

-:187: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#187: FILE: include/drm/drm_hdcp.h:312:
+int drm_connector_update_hdcp_topology_property(

total: 0 errors, 0 warnings, 4 checks, 192 lines checked
e96a375a2c0e drm/i915: Populate downstream info for HDCP
-:98: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#98: FILE: drivers/gpu/drm/i915/intel_hdcp.c:764:
+	if (drm_connector_update_hdcp_topology_property(&connector->base,
+						connector->hdcp.topology_info))

-:117: CHECK:OPEN_ENDED_LINE: Lines should not end with a '('
#117: FILE: drivers/gpu/drm/i915/intel_hdcp.c:800:
+			if (drm_connector_update_hdcp_topology_property(

-:157: CHECK:PARENTHESIS_ALIGNMENT: Alignment should match open parenthesis
#157: FILE: drivers/gpu/drm/i915/intel_hdcp.c:1632:
+		drm_connector_update_hdcp_topology_property(&connector->base,
+							  hdcp->topology_info);

total: 0 errors, 0 warnings, 3 checks, 187 lines checked

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

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

* ✗ Fi.CI.SPARSE: warning for HDCP2.2 Phase II (rev7)
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (14 preceding siblings ...)
  2019-04-18 11:17 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev7) Patchwork
@ 2019-04-18 11:25 ` Patchwork
  2019-04-18 11:45 ` ✓ Fi.CI.BAT: success " Patchwork
  2019-04-18 13:51 ` ✓ Fi.CI.IGT: " Patchwork
  17 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2019-04-18 11:25 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev7)
URL   : https://patchwork.freedesktop.org/series/57232/
State : warning

== Summary ==

$ dim sparse origin/drm-tip
Sparse version: v0.5.2
Commit: drm: move content protection property to mode_config
Okay!

Commit: drm/i915: debugfs: HDCP2.2 capability read
Okay!

Commit: drm: Add Content protection type property
Okay!

Commit: drm/i915: Attach content type property
Okay!

Commit: drm: revocation check at drm subsystem
+drivers/gpu/drm/drm_hdcp.c:247:6: warning: symbol 'drm_hdcp_request_srm' was not declared. Should it be static?
+drivers/gpu/drm/drm_hdcp.c:29:3: warning: symbol 'srm_data' was not declared. Should it be static?
+drivers/gpu/drm/drm_hdcp.c:329:6: warning: symbol 'drm_teardown_hdcp_srm' was not declared. Should it be static?
+./include/linux/slab.h:666:13: error: undefined identifier '__builtin_mul_overflow'
+./include/linux/slab.h:666:13: warning: call with no type!

Commit: drm/i915: SRM revocation check for HDCP1.4 and 2.2
Okay!

Commit: drm/hdcp: gathering hdcp related code into drm_hdcp.c
Okay!

Commit: drm: uevent for connector status change
Okay!

Commit: drm/hdcp: update content protection property with uevent
Okay!

Commit: drm/i915: update the hdcp state with uevent
Okay!

Commit: drm: Add CP downstream_info property
Okay!

Commit: drm/i915: Populate downstream info for HDCP
Okay!

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

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

* ✓ Fi.CI.BAT: success for HDCP2.2 Phase II (rev7)
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (15 preceding siblings ...)
  2019-04-18 11:25 ` ✗ Fi.CI.SPARSE: " Patchwork
@ 2019-04-18 11:45 ` Patchwork
  2019-04-18 13:51 ` ✓ Fi.CI.IGT: " Patchwork
  17 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2019-04-18 11:45 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev7)
URL   : https://patchwork.freedesktop.org/series/57232/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5952 -> Patchwork_12831
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://patchwork.freedesktop.org/api/1.0/series/57232/revisions/7/mbox/

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_12831:

### IGT changes ###

#### Possible regressions ####

  * {igt@kms_content_protection@srm} (NEW):
    - fi-icl-y:           NOTRUN -> SKIP
    - fi-icl-u3:          NOTRUN -> SKIP

  
New tests
---------

  New tests have been introduced between CI_DRM_5952 and Patchwork_12831:

### New IGT tests (1) ###

  * igt@kms_content_protection@srm:
    - Statuses : 42 skip(s)
    - Exec time: [0.0, 0.00] s

  

Known issues
------------

  Here are the changes found in Patchwork_12831 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@amdgpu/amd_basic@query-info:
    - fi-bsw-kefka:       NOTRUN -> SKIP [fdo#109271] +53

  * igt@gem_exec_basic@gtt-bsd2:
    - fi-byt-clapper:     NOTRUN -> SKIP [fdo#109271] +55

  * igt@i915_module_load@reload:
    - fi-blb-e6850:       PASS -> INCOMPLETE [fdo#107718]

  * igt@i915_module_load@reload-with-fault-injection:
    - fi-skl-6770hq:      PASS -> DMESG-WARN [fdo#108529] +2

  * igt@i915_selftest@live_contexts:
    - fi-bdw-gvtdvm:      PASS -> DMESG-FAIL [fdo#110235 ]

  * igt@kms_addfb_basic@addfb25-y-tiled-small:
    - fi-byt-n2820:       NOTRUN -> SKIP [fdo#109271] +54

  * igt@kms_busy@basic-flip-c:
    - fi-byt-clapper:     NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
    - fi-bsw-kefka:       NOTRUN -> SKIP [fdo#109271] / [fdo#109278]
    - fi-byt-n2820:       NOTRUN -> SKIP [fdo#109271] / [fdo#109278]

  * igt@kms_chamelium@hdmi-edid-read:
    - fi-hsw-peppy:       NOTRUN -> SKIP [fdo#109271] +49

  * igt@kms_content_protection@atomic:
    - fi-icl-u3:          NOTRUN -> FAIL [fdo#110322] +1
    - fi-skl-gvtdvm:      NOTRUN -> FAIL [fdo#110325] / [fdo#110336] +1
    - fi-glk-dsi:         NOTRUN -> SKIP [fdo#109271] +2
    - fi-skl-iommu:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-elk-e7500:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-whl-u:           NOTRUN -> SKIP [fdo#109271] +2
    - fi-cfl-8700k:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-pnv-d510:        NOTRUN -> SKIP [fdo#109271] +2
    - fi-snb-2520m:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-skl-guc:         NOTRUN -> SKIP [fdo#109271] +2
    - fi-skl-lmem:        NOTRUN -> FAIL [fdo#110336] +1
    - fi-apl-guc:         NOTRUN -> FAIL [fdo#110321] / [fdo#110336] +1

  * igt@kms_content_protection@legacy:
    - fi-cfl-guc:         NOTRUN -> SKIP [fdo#109271] +2
    - fi-snb-2600:        NOTRUN -> SKIP [fdo#109271] +2
    - fi-skl-6770hq:      NOTRUN -> FAIL [fdo#110336]
    - fi-bxt-j4205:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-kbl-r:           NOTRUN -> SKIP [fdo#109271] +2
    - fi-cfl-8109u:       NOTRUN -> FAIL [fdo#110336] +1
    - fi-kbl-guc:         NOTRUN -> SKIP [fdo#109271] +2
    - fi-bdw-gvtdvm:      NOTRUN -> SKIP [fdo#109271] +2
    - fi-gdg-551:         NOTRUN -> SKIP [fdo#109271] +2
    - fi-bwr-2160:        NOTRUN -> SKIP [fdo#109271] +2
    - fi-hsw-4770:        NOTRUN -> SKIP [fdo#109271] +2
    - fi-bxt-dsi:         NOTRUN -> SKIP [fdo#109271] +2
    - fi-ivb-3770:        NOTRUN -> SKIP [fdo#109271] +2
    - fi-kbl-8809g:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-icl-y:           NOTRUN -> SKIP [fdo#109300] +1

  * {igt@kms_content_protection@srm} (NEW):
    - fi-ilk-650:         NOTRUN -> SKIP [fdo#109271] +2
    - fi-bsw-n3050:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-hsw-4770r:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-cfl-8109u:       NOTRUN -> SKIP [fdo#109271]
    - fi-blb-e6850:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-bdw-5557u:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-kbl-7567u:       NOTRUN -> SKIP [fdo#109271]
    - fi-skl-6600u:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-byt-j1900:       NOTRUN -> SKIP [fdo#109271] +2
    - fi-skl-lmem:        NOTRUN -> SKIP [fdo#109271]
    - fi-apl-guc:         NOTRUN -> SKIP [fdo#109271]
    - fi-skl-6770hq:      NOTRUN -> SKIP [fdo#109271] +1
    - fi-skl-6700k2:      NOTRUN -> SKIP [fdo#109271]
    - fi-skl-6260u:       NOTRUN -> SKIP [fdo#109271]
    - fi-skl-gvtdvm:      NOTRUN -> SKIP [fdo#109271]
    - fi-kbl-x1275:       NOTRUN -> SKIP [fdo#109271]

  * igt@kms_flip@basic-flip-vs-dpms:
    - fi-skl-6770hq:      PASS -> SKIP [fdo#109271] +23

  * igt@kms_frontbuffer_tracking@basic:
    - fi-icl-u3:          PASS -> FAIL [fdo#103167]
    - fi-hsw-peppy:       NOTRUN -> DMESG-FAIL [fdo#102614] / [fdo#107814]
    - fi-byt-clapper:     NOTRUN -> FAIL [fdo#103167]

  * igt@runner@aborted:
    - fi-icl-dsi:         NOTRUN -> FAIL [fdo#109593]

  
#### Possible fixes ####

  * igt@i915_selftest@live_execlists:
    - fi-apl-guc:         INCOMPLETE [fdo#103927] / [fdo#109720] -> PASS

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#102614]: https://bugs.freedesktop.org/show_bug.cgi?id=102614
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#107718]: https://bugs.freedesktop.org/show_bug.cgi?id=107718
  [fdo#107814]: https://bugs.freedesktop.org/show_bug.cgi?id=107814
  [fdo#108529]: https://bugs.freedesktop.org/show_bug.cgi?id=108529
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109300]: https://bugs.freedesktop.org/show_bug.cgi?id=109300
  [fdo#109593]: https://bugs.freedesktop.org/show_bug.cgi?id=109593
  [fdo#109720]: https://bugs.freedesktop.org/show_bug.cgi?id=109720
  [fdo#110235 ]: https://bugs.freedesktop.org/show_bug.cgi?id=110235 
  [fdo#110321]: https://bugs.freedesktop.org/show_bug.cgi?id=110321
  [fdo#110322]: https://bugs.freedesktop.org/show_bug.cgi?id=110322
  [fdo#110325]: https://bugs.freedesktop.org/show_bug.cgi?id=110325
  [fdo#110336]: https://bugs.freedesktop.org/show_bug.cgi?id=110336


Participating hosts (44 -> 44)
------------------------------

  Additional (5): fi-hsw-peppy fi-icl-dsi fi-bsw-kefka fi-byt-n2820 fi-byt-clapper 
  Missing    (5): fi-ilk-m540 fi-byt-squawks fi-bsw-cyan fi-ctg-p8600 fi-bdw-samus 


Build changes
-------------

  * IGT: IGT_4956 -> IGTPW_2890
  * Linux: CI_DRM_5952 -> Patchwork_12831

  CI_DRM_5952: 65305a057be0e155321a0765a3a24115063f3a32 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2890: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2890/
  IGT_4956: 1d921615b0b706f25c856aa0eb096f274380c199 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_12831: e96a375a2c0e0a6ce1f604b2db86e31a14178cb7 @ git://anongit.freedesktop.org/gfx-ci/linux


== Linux commits ==

e96a375a2c0e drm/i915: Populate downstream info for HDCP
115e48f3f606 drm: Add CP downstream_info property
5c248b12771b drm/i915: update the hdcp state with uevent
a3e81ac66413 drm/hdcp: update content protection property with uevent
df0f1eb5d4cd drm: uevent for connector status change
f509333fff7e drm/hdcp: gathering hdcp related code into drm_hdcp.c
30d4513a2b5a drm/i915: SRM revocation check for HDCP1.4 and 2.2
1c19c4f8620b drm: revocation check at drm subsystem
d8db5b5b9147 drm/i915: Attach content type property
f394967e1c97 drm: Add Content protection type property
49dbee2b7e34 drm/i915: debugfs: HDCP2.2 capability read
4c5fcb196eb7 drm: move content protection property to mode_config

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12831/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* ✓ Fi.CI.IGT: success for HDCP2.2 Phase II (rev7)
  2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
                   ` (16 preceding siblings ...)
  2019-04-18 11:45 ` ✓ Fi.CI.BAT: success " Patchwork
@ 2019-04-18 13:51 ` Patchwork
  17 siblings, 0 replies; 33+ messages in thread
From: Patchwork @ 2019-04-18 13:51 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx

== Series Details ==

Series: HDCP2.2 Phase II (rev7)
URL   : https://patchwork.freedesktop.org/series/57232/
State : success

== Summary ==

CI Bug Log - changes from CI_DRM_5952_full -> Patchwork_12831_full
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in Patchwork_12831_full:

### IGT changes ###

#### Possible regressions ####

  * {igt@audio@hdmi-integrity} (NEW):
    - shard-kbl:          NOTRUN -> FAIL +1
    - shard-skl:          NOTRUN -> FAIL +1
    - shard-glk:          NOTRUN -> FAIL
    - shard-iclb:         NOTRUN -> FAIL +1
    - shard-snb:          NOTRUN -> FAIL +1

  * {igt@audio@hdmi-integrity-after-suspend} (NEW):
    - shard-apl:          NOTRUN -> FAIL +1
    - shard-glk:          NOTRUN -> TIMEOUT

  * {igt@kms_content_protection@type1} (NEW):
    - shard-iclb:         NOTRUN -> SKIP +3

  
New tests
---------

  New tests have been introduced between CI_DRM_5952_full and Patchwork_12831_full:

### New IGT tests (6) ###

  * igt@audio@hdmi-integrity:
    - Statuses : 6 fail(s)
    - Exec time: [0.24, 7.13] s

  * igt@audio@hdmi-integrity-after-suspend:
    - Statuses : 5 fail(s) 1 timeout(s)
    - Exec time: [0.19, 543.63] s

  * igt@kms_content_protection@content_type_change:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@kms_content_protection@srm:
    - Statuses : 5 skip(s)
    - Exec time: [0.0, 0.00] s

  * igt@kms_content_protection@type1:
    - Statuses : 6 skip(s)
    - Exec time: [0.0, 0.01] s

  * igt@kms_content_protection@type1_mei_interface:
    - Statuses : 6 skip(s)
    - Exec time: [0.00, 0.01] s

  

Known issues
------------

  Here are the changes found in Patchwork_12831_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_mocs_settings@mocs-reset-bsd2:
    - shard-snb:          NOTRUN -> SKIP [fdo#109271] +37

  * igt@gem_tiled_swapping@non-threaded:
    - shard-iclb:         PASS -> INCOMPLETE [fdo#107713] / [fdo#108686]

  * igt@i915_pm_rc6_residency@rc6-accuracy:
    - shard-snb:          PASS -> SKIP [fdo#109271]

  * igt@i915_pm_rpm@universal-planes-dpms:
    - shard-skl:          NOTRUN -> INCOMPLETE [fdo#107807] +1

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-apl:          PASS -> DMESG-WARN [fdo#108566] +3

  * igt@kms_busy@extended-modeset-hang-oldfb-with-reset-render-f:
    - shard-kbl:          NOTRUN -> SKIP [fdo#109271] / [fdo#109278]

  * {igt@kms_content_protection@srm} (NEW):
    - shard-glk:          NOTRUN -> SKIP [fdo#109271] +3

  * {igt@kms_content_protection@type1_mei_interface} (NEW):
    - shard-kbl:          NOTRUN -> SKIP [fdo#109271] +6
    - shard-apl:          NOTRUN -> SKIP [fdo#109271] +3

  * igt@kms_cursor_crc@cursor-128x128-random:
    - shard-apl:          PASS -> FAIL [fdo#103232]

  * igt@kms_flip@flip-vs-expired-vblank-interruptible:
    - shard-skl:          PASS -> FAIL [fdo#105363]

  * igt@kms_flip@flip-vs-suspend-interruptible:
    - shard-kbl:          PASS -> DMESG-WARN [fdo#108566]

  * igt@kms_flip@modeset-vs-vblank-race-interruptible:
    - shard-skl:          PASS -> FAIL [fdo#103060]

  * igt@kms_flip_tiling@flip-to-x-tiled:
    - shard-iclb:         PASS -> FAIL [fdo#108134]

  * igt@kms_frontbuffer_tracking@fbc-1p-primscrn-indfb-msflip-blt:
    - shard-iclb:         PASS -> FAIL [fdo#103167] +4

  * igt@kms_frontbuffer_tracking@fbc-2p-scndscrn-shrfb-msflip-blt:
    - shard-glk:          PASS -> FAIL [fdo#103167]

  * igt@kms_lease@cursor_implicit_plane:
    - shard-snb:          NOTRUN -> FAIL [fdo#110278]

  * igt@kms_pipe_crc_basic@hang-read-crc-pipe-f:
    - shard-snb:          NOTRUN -> SKIP [fdo#109271] / [fdo#109278] +4

  * igt@kms_pipe_crc_basic@nonblocking-crc-pipe-e:
    - shard-skl:          NOTRUN -> SKIP [fdo#109271] / [fdo#109278] +22

  * igt@kms_plane_alpha_blend@pipe-a-alpha-7efc:
    - shard-skl:          NOTRUN -> FAIL [fdo#108145] +5

  * igt@kms_plane_scaling@pipe-b-scaler-with-pixel-format:
    - shard-glk:          PASS -> SKIP [fdo#109271] / [fdo#109278]

  * igt@kms_psr@psr2_cursor_render:
    - shard-iclb:         PASS -> SKIP [fdo#109441] +2

  * igt@kms_rotation_crc@multiplane-rotation:
    - shard-kbl:          PASS -> DMESG-FAIL [fdo#105763]

  * igt@kms_sysfs_edid_timing:
    - shard-iclb:         PASS -> FAIL [fdo#100047]

  * igt@perf_pmu@busy-accuracy-50-vcs1:
    - shard-skl:          NOTRUN -> SKIP [fdo#109271] +222

  
#### Possible fixes ####

  * igt@debugfs_test@read_all_entries_display_off:
    - shard-skl:          INCOMPLETE [fdo#104108] -> PASS

  * igt@gem_eio@unwedge-stress:
    - shard-glk:          FAIL [fdo#109661] -> PASS

  * igt@gem_exec_suspend@basic-s3:
    - shard-kbl:          INCOMPLETE [fdo#103665] -> PASS

  * igt@i915_pm_rpm@dpms-mode-unset-lpsp:
    - shard-skl:          INCOMPLETE [fdo#107807] -> PASS

  * igt@kms_frontbuffer_tracking@basic:
    - shard-snb:          SKIP [fdo#109271] -> PASS +1

  * igt@kms_frontbuffer_tracking@fbc-suspend:
    - shard-kbl:          DMESG-WARN [fdo#103313] -> PASS
    - shard-apl:          DMESG-WARN [fdo#108566] -> PASS +1

  * igt@kms_frontbuffer_tracking@fbcpsr-1p-primscrn-pri-indfb-draw-blt:
    - shard-iclb:         FAIL [fdo#103167] -> PASS +7

  * igt@kms_plane@pixel-format-pipe-a-planes-source-clamping:
    - shard-glk:          SKIP [fdo#109271] -> PASS

  * igt@kms_plane_alpha_blend@pipe-a-coverage-7efc:
    - shard-skl:          FAIL [fdo#108145] -> PASS +1

  * igt@kms_rotation_crc@multiplane-rotation-cropping-bottom:
    - shard-kbl:          DMESG-FAIL [fdo#105763] -> PASS

  
#### Warnings ####

  * igt@kms_plane@plane-panning-bottom-right-suspend-pipe-b-planes:
    - shard-apl:          DMESG-WARN [fdo#108566] -> INCOMPLETE [fdo#103927]

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#100047]: https://bugs.freedesktop.org/show_bug.cgi?id=100047
  [fdo#103060]: https://bugs.freedesktop.org/show_bug.cgi?id=103060
  [fdo#103167]: https://bugs.freedesktop.org/show_bug.cgi?id=103167
  [fdo#103232]: https://bugs.freedesktop.org/show_bug.cgi?id=103232
  [fdo#103313]: https://bugs.freedesktop.org/show_bug.cgi?id=103313
  [fdo#103665]: https://bugs.freedesktop.org/show_bug.cgi?id=103665
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#104108]: https://bugs.freedesktop.org/show_bug.cgi?id=104108
  [fdo#105363]: https://bugs.freedesktop.org/show_bug.cgi?id=105363
  [fdo#105763]: https://bugs.freedesktop.org/show_bug.cgi?id=105763
  [fdo#107713]: https://bugs.freedesktop.org/show_bug.cgi?id=107713
  [fdo#107807]: https://bugs.freedesktop.org/show_bug.cgi?id=107807
  [fdo#108134]: https://bugs.freedesktop.org/show_bug.cgi?id=108134
  [fdo#108145]: https://bugs.freedesktop.org/show_bug.cgi?id=108145
  [fdo#108566]: https://bugs.freedesktop.org/show_bug.cgi?id=108566
  [fdo#108686]: https://bugs.freedesktop.org/show_bug.cgi?id=108686
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109278]: https://bugs.freedesktop.org/show_bug.cgi?id=109278
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#109661]: https://bugs.freedesktop.org/show_bug.cgi?id=109661
  [fdo#110278]: https://bugs.freedesktop.org/show_bug.cgi?id=110278


Participating hosts (10 -> 9)
------------------------------

  Missing    (1): shard-hsw 


Build changes
-------------

  * IGT: IGT_4956 -> IGTPW_2890
  * Linux: CI_DRM_5952 -> Patchwork_12831

  CI_DRM_5952: 65305a057be0e155321a0765a3a24115063f3a32 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_2890: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_2890/
  IGT_4956: 1d921615b0b706f25c856aa0eb096f274380c199 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
  Patchwork_12831: e96a375a2c0e0a6ce1f604b2db86e31a14178cb7 @ git://anongit.freedesktop.org/gfx-ci/linux
  piglit_4509: fdc5a4ca11124ab8413c7988896eec4c97336694 @ git://anongit.freedesktop.org/piglit

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/Patchwork_12831/
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

* Re: [PATCH v5 01/12] drm: move content protection property to mode_config
  2019-04-18  8:57 ` [PATCH v5 01/12] drm: move content protection property to mode_config Ramalingam C
@ 2019-04-23  7:38   ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-23  7:38 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Thu, Apr 18, 2019 at 02:27:54PM +0530, Ramalingam C wrote:
> Content protection property is created once and stored in
> drm_mode_config. And attached to all HDCP capable connectors.
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/drm_atomic_uapi.c |  4 ++--
>  drivers/gpu/drm/drm_connector.c   | 13 +++++++------
>  include/drm/drm_connector.h       |  6 ------
>  include/drm/drm_mode_config.h     |  6 ++++++
>  4 files changed, 15 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index ea797d4c82ee..002dcede7915 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -727,7 +727,7 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
>  		state->content_type = val;
>  	} else if (property == connector->scaling_mode_property) {
>  		state->scaling_mode = val;
> -	} else if (property == connector->content_protection_property) {
> +	} else if (property == config->content_protection_property) {
>  		if (val == DRM_MODE_CONTENT_PROTECTION_ENABLED) {
>  			DRM_DEBUG_KMS("only drivers can set CP Enabled\n");
>  			return -EINVAL;
> @@ -807,7 +807,7 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
>  		*val = state->colorspace;
>  	} else if (property == connector->scaling_mode_property) {
>  		*val = state->scaling_mode;
> -	} else if (property == connector->content_protection_property) {
> +	} else if (property == config->content_protection_property) {
>  		*val = state->content_protection;
>  	} else if (property == config->writeback_fb_id_property) {
>  		/* Writeback framebuffer is one-shot, write and forget */
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 2355124849db..7c0eda9cca60 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -1534,18 +1534,19 @@ int drm_connector_attach_content_protection_property(
>  		struct drm_connector *connector)
>  {
>  	struct drm_device *dev = connector->dev;
> -	struct drm_property *prop;
> +	struct drm_property *prop =
> +			dev->mode_config.content_protection_property;
>  
> -	prop = drm_property_create_enum(dev, 0, "Content Protection",
> -					drm_cp_enum_list,
> -					ARRAY_SIZE(drm_cp_enum_list));
> +	if (!prop)
> +		prop = drm_property_create_enum(dev, 0, "Content Protection",
> +						drm_cp_enum_list,
> +						ARRAY_SIZE(drm_cp_enum_list));
>  	if (!prop)
>  		return -ENOMEM;
>  
>  	drm_object_attach_property(&connector->base, prop,
>  				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
> -
> -	connector->content_protection_property = prop;
> +	dev->mode_config.content_protection_property = prop;
>  
>  	return 0;
>  }
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 02a131202add..5e41942e5679 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -1061,12 +1061,6 @@ struct drm_connector {
>  	 */
>  	struct drm_property *vrr_capable_property;
>  
> -	/**
> -	 * @content_protection_property: DRM ENUM property for content
> -	 * protection. See drm_connector_attach_content_protection_property().
> -	 */
> -	struct drm_property *content_protection_property;
> -
>  	/**
>  	 * @colorspace_property: Connector property to set the suitable
>  	 * colorspace supported by the sink.
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 7f60e8eb269a..5764ee3c7453 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -836,6 +836,12 @@ struct drm_mode_config {
>  	 */
>  	struct drm_property *writeback_out_fence_ptr_property;
>  
> +	/**
> +	 * @content_protection_property: DRM ENUM property for content
> +	 * protection. See drm_connector_attach_content_protection_property().
> +	 */
> +	struct drm_property *content_protection_property;
> +
>  	/* dumb ioctl parameters */
>  	uint32_t preferred_depth, prefer_shadow;
>  
> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
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] 33+ messages in thread

* Re: [PATCH v5 03/12] drm: Add Content protection type property
  2019-04-18  8:57 ` [PATCH v5 03/12] drm: Add Content protection type property Ramalingam C
@ 2019-04-23  7:44   ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-23  7:44 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Thu, Apr 18, 2019 at 02:27:56PM +0530, Ramalingam C wrote:
> This patch adds a DRM ENUM property to the selected connectors.
> This property is used for mentioning the protected content's type
> from userspace to kernel HDCP authentication.
> 
> Type of the stream is decided by the protected content providers.
> Type 0 content can be rendered on any HDCP protected display wires.
> But Type 1 content can be rendered only on HDCP2.2 protected paths.
> 
> So when a userspace sets this property to Type 1 and starts the HDCP
> enable, kernel will honour it only if HDCP2.2 authentication is through
> for type 1. Else HDCP enable will be failed.
> 
> v2:
>   cp_content_type is replaced with content_protection_type [daniel]
>   check at atomic_set_property is removed [Maarten]
> v3:
>   %s/content_protection_type/hdcp_content_type [Pekka]
> v4:
>   property is created for the first requested connector and then reused.
> 	[Danvet]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic_uapi.c |  4 +++
>  drivers/gpu/drm/drm_connector.c   | 53 ++++++++++++++++++++++++++++++-
>  drivers/gpu/drm/i915/intel_hdcp.c |  4 ++-
>  include/drm/drm_connector.h       |  9 +++++-
>  include/drm/drm_mode_config.h     |  6 ++++
>  include/uapi/drm/drm_mode.h       |  4 +++
>  6 files changed, 77 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index 002dcede7915..0b0747869963 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -733,6 +733,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector,
>  			return -EINVAL;
>  		}
>  		state->content_protection = val;
> +	} else if (property == config->hdcp_content_type_property) {
> +		state->hdcp_content_type = val;
>  	} else if (property == connector->colorspace_property) {
>  		state->colorspace = val;
>  	} else if (property == config->writeback_fb_id_property) {
> @@ -809,6 +811,8 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
>  		*val = state->scaling_mode;
>  	} else if (property == config->content_protection_property) {
>  		*val = state->content_protection;
> +	} else if (property == config->hdcp_content_type_property) {
> +		*val = state->hdcp_content_type;
>  	} else if (property == config->writeback_fb_id_property) {
>  		/* Writeback framebuffer is one-shot, write and forget */
>  		*val = 0;
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 7c0eda9cca60..03907d13ef66 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -857,6 +857,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_hdcp_content_type_enum_list[] = {
> +	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
> +	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
> +};
> +DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> +		 drm_hdcp_content_type_enum_list)
> +
>  /**
>   * DOC: standard connector properties
>   *
> @@ -962,6 +969,23 @@ 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).
> + * HDCP 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

"upcoming" sounds a bit like "in a future patch", which is confusing in
documentation. Maybe "to be displayed" instead of "upcoming"?

> + *	the owner of the stream, as HDCP Type0 or HDCP Type1.
> + *
> + *	The value of the property can be one the below:
> + *	  - DRM_MODE_HDCP_CONTENT_TYPE0 = 0
> + *		HDCP Type0 streams can be transmitted on a link which is
> + *		encrypted with HDCP 1.4 or HDCP 2.2.
> + *	  - DRM_MODE_HDCP_CONTENT_TYPE1 = 1
> + *		HDCP Type1 streams can be transmitted on a link which is
> + *		encrypted only with HDCP 2.2.
> + *
> + *	Please note this content type is introduced at HDCP 2.2 and used in its
> + *	authentication process.

I'd replace this with "Note that the HDCP Content Type property is
optional, and defaults to type 0. It is only exposed by drivers supporting
HDCP 2.x." I think that makes it clearer for userspace people what this
means.

> If content type is changed when
> + *	content_protection is not UNDESIRED, then kernel will disable the HDCP
> + *	and re-enable with new type in the same atomic commit
>   *
>   * max bpc:
>   *	This range property is used by userspace to limit the bit depth. When
> @@ -1520,18 +1544,29 @@ EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
>   * property
>   *
>   * @connector: connector to attach CP property on.
> + * @hdcp_content_type: is HDCP Content Type property needed for connector
>   *
>   * This is used to add support for content protection on select connectors.
>   * Content Protection is intentionally vague to allow for different underlying
>   * technologies, however it is most implemented by HDCP.
>   *
> + * When hdcp_content_type is true enum property called HDCP Content Type is
> + * created (if it is not already) and attached to the connector.
> + *
> + * This property is used for sending the protected content's stream type
> + * from userspace to kernel on selected connectors. Protected content provider
> + * will decide their type of their content and declare the same to kernel.
> + *
> + * Content type will be used during the HDCP 2.2 authentication.
> + * Content type will be set to &drm_connector_state.hdcp_content_type.
> + *
>   * The content protection will be set to &drm_connector_state.content_protection
>   *
>   * Returns:
>   * Zero on success, negative errno on failure.
>   */
>  int drm_connector_attach_content_protection_property(
> -		struct drm_connector *connector)
> +		struct drm_connector *connector, bool hdcp_content_type)
>  {
>  	struct drm_device *dev = connector->dev;
>  	struct drm_property *prop =
> @@ -1548,6 +1583,22 @@ int drm_connector_attach_content_protection_property(
>  				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
>  	dev->mode_config.content_protection_property = prop;
>  
> +	if (!hdcp_content_type)
> +		return 0;
> +
> +	prop = dev->mode_config.hdcp_content_type_property;
> +	if (!prop)
> +		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
> +					drm_hdcp_content_type_enum_list,
> +					ARRAY_SIZE(
> +					drm_hdcp_content_type_enum_list));
> +	if (!prop)
> +		return -ENOMEM;
> +
> +	drm_object_attach_property(&connector->base, prop,
> +				   DRM_MODE_HDCP_CONTENT_TYPE0);
> +	dev->mode_config.hdcp_content_type_property = prop;
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> index 440fef448feb..a61391d374e8 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -1798,7 +1798,9 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	if (!shim)
>  		return -EINVAL;
>  
> -	ret = drm_connector_attach_content_protection_property(&connector->base);
> +	ret =
> +	drm_connector_attach_content_protection_property(&connector->base,
> +							 false);
>  	if (ret)
>  		return ret;
>  
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 5e41942e5679..2d2c2d5e7681 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -556,6 +556,12 @@ struct drm_connector_state {
>  	 */
>  	unsigned int content_type;
>  
> +	/**
> +	 * @hdcp_content_type: Connector property to pass the type of
> +	 * protected content. This is most commonly used for HDCP.
> +	 */
> +	unsigned int hdcp_content_type;
> +
>  	/**
>  	 * @scaling_mode: Connector property to control the
>  	 * upscaling, mostly used for built-in panels.
> @@ -1326,6 +1332,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_hdcp_content_type_name(int val);
>  
>  int drm_mode_create_dvi_i_properties(struct drm_device *dev);
>  int drm_mode_create_tv_margin_properties(struct drm_device *dev);
> @@ -1340,7 +1347,7 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
>  int drm_connector_attach_vrr_capable_property(
>  		struct drm_connector *connector);
>  int drm_connector_attach_content_protection_property(
> -		struct drm_connector *connector);
> +		struct drm_connector *connector, bool hdcp_content_type);
>  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/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index 5764ee3c7453..b359b5b71eb9 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -842,6 +842,12 @@ struct drm_mode_config {
>  	 */
>  	struct drm_property *content_protection_property;
>  
> +	/**
> +	 * @hdcp_content_type_property: DRM ENUM property for type of
> +	 * Protected Content.
> +	 */
> +	struct drm_property *hdcp_content_type_property;
> +
>  	/* dumb ioctl parameters */
>  	uint32_t preferred_depth, prefer_shadow;
>  
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 83cd1636b9be..8ac03351fdee 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -209,6 +209,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_HDCP_CONTENT_TYPE0		0
> +#define DRM_MODE_HDCP_CONTENT_TYPE1		1
> +

With the kernel doc nits addressed:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

>  struct drm_mode_modeinfo {
>  	__u32 clock;
>  	__u16 hdisplay;
> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
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] 33+ messages in thread

* Re: [PATCH v5 04/12] drm/i915: Attach content type property
  2019-04-18  8:57 ` [PATCH v5 04/12] drm/i915: Attach content " Ramalingam C
@ 2019-04-23  8:11   ` Daniel Vetter
  2019-04-23 11:17     ` Ramalingam C
  0 siblings, 1 reply; 33+ messages in thread
From: Daniel Vetter @ 2019-04-23  8:11 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel, gwan-gyeong.mun

On Thu, Apr 18, 2019 at 02:27:57PM +0530, Ramalingam C wrote:
> 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.
> 
> v2:
>   s/cp_content_type/content_protection_type [daniel]
>   disable at hdcp_atomic_check to avoid check at atomic_set_property
> 	[Maarten]
> v3:
>   s/content_protection_type/hdcp_content_type [Pekka]
> v4:
>   hdcp disable incase of type change is moved into commit [daniel].
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_ddi.c  | 38 ++++++++++++++++++++++++---
>  drivers/gpu/drm/i915/intel_hdcp.c | 43 ++++++++++++++++++++-----------
>  drivers/gpu/drm/i915/intel_hdcp.h |  2 +-
>  3 files changed, 63 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> index 24f9106efcc6..dd9bea840937 100644
> --- a/drivers/gpu/drm/i915/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/intel_ddi.c
> @@ -3476,7 +3476,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->hdcp_content_type);
>  }
>  
>  static void intel_disable_ddi_dp(struct intel_encoder *encoder,
> @@ -3545,15 +3546,44 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
>  				  const struct intel_crtc_state *crtc_state,
>  				  const struct drm_connector_state *conn_state)
>  {
> +	struct intel_connector *connector =
> +				to_intel_connector(conn_state->connector);
> +	struct intel_hdcp *hdcp = &connector->hdcp;
> +	bool  re_enable_hdcp = false;
> +	int ret = -EINVAL;
> +
>  	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
>  		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
>  
> +	/*
> +	 * During the HDCP encryption session if Type change is requested,
> +	 * disable the HDCP and reenable it with new TYPE value.
> +	 */
>  	if (conn_state->content_protection ==
> -	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> -		intel_hdcp_enable(to_intel_connector(conn_state->connector));
> +	    DRM_MODE_CONTENT_PROTECTION_ENABLED &&
> +	    conn_state->hdcp_content_type != hdcp->content_type) {
> +		intel_hdcp_disable(to_intel_connector(conn_state->connector));
> +		re_enable_hdcp = true;
> +	}
> +
> +	if (conn_state->content_protection ==
> +	    DRM_MODE_CONTENT_PROTECTION_DESIRED || re_enable_hdcp)
> +		ret = intel_hdcp_enable(connector,
> +					(u8)conn_state->hdcp_content_type);
>  	else if (conn_state->content_protection ==
>  		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> -		intel_hdcp_disable(to_intel_connector(conn_state->connector));
> +		intel_hdcp_disable(connector);
> +
> +	/*
> +	 * During Type change handling re-enabling of the HDCP failed. Hence
> +	 * changes state as ENABLED->DESIRED.
> +	 */
> +	if (ret && re_enable_hdcp) {
> +		mutex_lock(&hdcp->mutex);
> +		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> +		schedule_work(&hdcp->prop_work);
> +		mutex_unlock(&hdcp->mutex);
> +	}

I'm unhappy with the convoluted logic here. It's correct I think but
fairly hard to follow. What about this instead?

	unsigned int content_protection = conn_state->content_protection;
	bool content_protection_type_changed =
		conn_state->hdcp_content_type != hdcp->content_type;

	if (conn_state->content_protection ==
		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED ||
	    content_protection_type_changed)
		intel_hdcp_disable(to_intel_connector(conn_state->connector));

	/* Make sure we pick up type changes */
	if (content_protection_type_changed) {
		mutex_lock(&hdcp->mutex);
		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
		schedule_work(&hdcp->prop_work);
		mutex_unlock(&hdcp->mutex);
	}

	if (conn_state->content_protection ==
	    DRM_MODE_CONTENT_PROTECTION_DESIRED ||
	    content_protection_type_changed)
		intel_hdcp_enable(to_intel_connector(conn_state->connector));

Idea is to only have one disable and one enable call, and make sure the
enable picks up our content type change no matter what. But not sure that
it's really clearer. Thoughts?

Aside from this lgtm.
-Daniel


>  }
>  
>  static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> index a61391d374e8..772974697b5a 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -1717,14 +1717,15 @@ static const struct component_ops i915_hdcp_component_ops = {
>  	.unbind = i915_hdcp_component_unbind,
>  };
>  
> -static inline int initialize_hdcp_port_data(struct intel_connector *connector)
> +static inline int initialize_hdcp_port_data(struct intel_connector *connector,
> +					    const struct intel_hdcp_shim *shim)
>  {
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	struct hdcp_port_data *data = &hdcp->port_data;
>  
>  	data->port = connector->encoder->port;
>  	data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
> -	data->protocol = (u8)hdcp->shim->protocol;
> +	data->protocol = (u8)shim->protocol;
>  
>  	data->k = 1;
>  	if (!data->streams)
> @@ -1774,12 +1775,13 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
>  	}
>  }
>  
> -static void intel_hdcp2_init(struct intel_connector *connector)
> +static void intel_hdcp2_init(struct intel_connector *connector,
> +			     const struct intel_hdcp_shim *shim)
>  {
>  	struct intel_hdcp *hdcp = &connector->hdcp;
>  	int ret;
>  
> -	ret = initialize_hdcp_port_data(connector);
> +	ret = initialize_hdcp_port_data(connector, shim);
>  	if (ret) {
>  		DRM_DEBUG_KMS("Mei hdcp data init failed\n");
>  		return;
> @@ -1798,25 +1800,28 @@ int intel_hdcp_init(struct intel_connector *connector,
>  	if (!shim)
>  		return -EINVAL;
>  
> +	if (is_hdcp2_supported(dev_priv))
> +		intel_hdcp2_init(connector, shim);
> +
>  	ret =
>  	drm_connector_attach_content_protection_property(&connector->base,
> -							 false);
> -	if (ret)
> +							 hdcp->hdcp2_supported);
> +	if (ret) {
> +		hdcp->hdcp2_supported = false;
> +		kfree(hdcp->port_data.streams);
>  		return ret;
> +	}
>  
>  	hdcp->shim = shim;
>  	mutex_init(&hdcp->mutex);
>  	INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work);
>  	INIT_WORK(&hdcp->prop_work, intel_hdcp_prop_work);
> -
> -	if (is_hdcp2_supported(dev_priv))
> -		intel_hdcp2_init(connector);
>  	init_waitqueue_head(&hdcp->cp_irq_queue);
>  
>  	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;
> @@ -1827,6 +1832,7 @@ 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
> @@ -1838,8 +1844,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_HDCP_CONTENT_TYPE1) {
>  		ret = _intel_hdcp_enable(connector);
>  	}
>  
> @@ -1921,12 +1931,15 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
>  
>  	/*
>  	 * Nothing to do if the state didn't change, or HDCP was activated since
> -	 * the last commit
> +	 * the last commit. And also no change in hdcp content type.
>  	 */
>  	if (old_cp == new_cp ||
>  	    (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
> -	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED))
> -		return;
> +	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) {
> +		if (old_state->hdcp_content_type ==
> +				new_state->hdcp_content_type)
> +			return;
> +	}
>  
>  	crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
>  						   new_state->crtc);
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.h b/drivers/gpu/drm/i915/intel_hdcp.h
> index be8da85c866a..13555b054930 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.h
> +++ b/drivers/gpu/drm/i915/intel_hdcp.h
> @@ -21,7 +21,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);
> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 04/12] drm/i915: Attach content type property
  2019-04-23  8:11   ` Daniel Vetter
@ 2019-04-23 11:17     ` Ramalingam C
  2019-04-23 12:10       ` Daniel Vetter
  0 siblings, 1 reply; 33+ messages in thread
From: Ramalingam C @ 2019-04-23 11:17 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx, dri-devel, gwan-gyeong.mun

On 2019-04-23 at 10:11:48 +0200, Daniel Vetter wrote:
> On Thu, Apr 18, 2019 at 02:27:57PM +0530, Ramalingam C wrote:
> > 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.
> > 
> > v2:
> >   s/cp_content_type/content_protection_type [daniel]
> >   disable at hdcp_atomic_check to avoid check at atomic_set_property
> > 	[Maarten]
> > v3:
> >   s/content_protection_type/hdcp_content_type [Pekka]
> > v4:
> >   hdcp disable incase of type change is moved into commit [daniel].
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > ---
> >  drivers/gpu/drm/i915/intel_ddi.c  | 38 ++++++++++++++++++++++++---
> >  drivers/gpu/drm/i915/intel_hdcp.c | 43 ++++++++++++++++++++-----------
> >  drivers/gpu/drm/i915/intel_hdcp.h |  2 +-
> >  3 files changed, 63 insertions(+), 20 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > index 24f9106efcc6..dd9bea840937 100644
> > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > @@ -3476,7 +3476,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->hdcp_content_type);
> >  }
> >  
> >  static void intel_disable_ddi_dp(struct intel_encoder *encoder,
> > @@ -3545,15 +3546,44 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
> >  				  const struct intel_crtc_state *crtc_state,
> >  				  const struct drm_connector_state *conn_state)
> >  {
> > +	struct intel_connector *connector =
> > +				to_intel_connector(conn_state->connector);
> > +	struct intel_hdcp *hdcp = &connector->hdcp;
> > +	bool  re_enable_hdcp = false;
> > +	int ret = -EINVAL;
> > +
> >  	if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> >  		intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
> >  
> > +	/*
> > +	 * During the HDCP encryption session if Type change is requested,
> > +	 * disable the HDCP and reenable it with new TYPE value.
> > +	 */
> >  	if (conn_state->content_protection ==
> > -	    DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > -		intel_hdcp_enable(to_intel_connector(conn_state->connector));
> > +	    DRM_MODE_CONTENT_PROTECTION_ENABLED &&
> > +	    conn_state->hdcp_content_type != hdcp->content_type) {
> > +		intel_hdcp_disable(to_intel_connector(conn_state->connector));
> > +		re_enable_hdcp = true;
> > +	}
> > +
> > +	if (conn_state->content_protection ==
> > +	    DRM_MODE_CONTENT_PROTECTION_DESIRED || re_enable_hdcp)
> > +		ret = intel_hdcp_enable(connector,
> > +					(u8)conn_state->hdcp_content_type);
> >  	else if (conn_state->content_protection ==
> >  		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> > -		intel_hdcp_disable(to_intel_connector(conn_state->connector));
> > +		intel_hdcp_disable(connector);
> > +
> > +	/*
> > +	 * During Type change handling re-enabling of the HDCP failed. Hence
> > +	 * changes state as ENABLED->DESIRED.
> > +	 */
> > +	if (ret && re_enable_hdcp) {
> > +		mutex_lock(&hdcp->mutex);
> > +		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> > +		schedule_work(&hdcp->prop_work);
> > +		mutex_unlock(&hdcp->mutex);
> > +	}
> 
> I'm unhappy with the convoluted logic here. It's correct I think but
> fairly hard to follow. What about this instead?
> 
> 	unsigned int content_protection = conn_state->content_protection;
> 	bool content_protection_type_changed =
> 		conn_state->hdcp_content_type != hdcp->content_type;
> 
> 	if (conn_state->content_protection ==
> 		 DRM_MODE_CONTENT_PROTECTION_UNDESIRED ||
> 	    content_protection_type_changed)
> 		intel_hdcp_disable(to_intel_connector(conn_state->connector));
> 
> 	/* Make sure we pick up type changes */
> 	if (content_protection_type_changed) {
> 		mutex_lock(&hdcp->mutex);
> 		hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> 		schedule_work(&hdcp->prop_work);
> 		mutex_unlock(&hdcp->mutex);
> 	}
> 
> 	if (conn_state->content_protection ==
> 	    DRM_MODE_CONTENT_PROTECTION_DESIRED ||
> 	    content_protection_type_changed)
> 		intel_hdcp_enable(to_intel_connector(conn_state->connector));
> 
> Idea is to only have one disable and one enable call, and make sure the
> enable picks up our content type change no matter what. But not sure that
> it's really clearer. Thoughts?
Sure. More simplified. I will add your reviewed-by with this change to
the patch. Thanks.

- Ram
> 
> Aside from this lgtm.
> -Daniel
> 
> 
> >  }
> >  
> >  static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
> > diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> > index a61391d374e8..772974697b5a 100644
> > --- a/drivers/gpu/drm/i915/intel_hdcp.c
> > +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> > @@ -1717,14 +1717,15 @@ static const struct component_ops i915_hdcp_component_ops = {
> >  	.unbind = i915_hdcp_component_unbind,
> >  };
> >  
> > -static inline int initialize_hdcp_port_data(struct intel_connector *connector)
> > +static inline int initialize_hdcp_port_data(struct intel_connector *connector,
> > +					    const struct intel_hdcp_shim *shim)
> >  {
> >  	struct intel_hdcp *hdcp = &connector->hdcp;
> >  	struct hdcp_port_data *data = &hdcp->port_data;
> >  
> >  	data->port = connector->encoder->port;
> >  	data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
> > -	data->protocol = (u8)hdcp->shim->protocol;
> > +	data->protocol = (u8)shim->protocol;
> >  
> >  	data->k = 1;
> >  	if (!data->streams)
> > @@ -1774,12 +1775,13 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
> >  	}
> >  }
> >  
> > -static void intel_hdcp2_init(struct intel_connector *connector)
> > +static void intel_hdcp2_init(struct intel_connector *connector,
> > +			     const struct intel_hdcp_shim *shim)
> >  {
> >  	struct intel_hdcp *hdcp = &connector->hdcp;
> >  	int ret;
> >  
> > -	ret = initialize_hdcp_port_data(connector);
> > +	ret = initialize_hdcp_port_data(connector, shim);
> >  	if (ret) {
> >  		DRM_DEBUG_KMS("Mei hdcp data init failed\n");
> >  		return;
> > @@ -1798,25 +1800,28 @@ int intel_hdcp_init(struct intel_connector *connector,
> >  	if (!shim)
> >  		return -EINVAL;
> >  
> > +	if (is_hdcp2_supported(dev_priv))
> > +		intel_hdcp2_init(connector, shim);
> > +
> >  	ret =
> >  	drm_connector_attach_content_protection_property(&connector->base,
> > -							 false);
> > -	if (ret)
> > +							 hdcp->hdcp2_supported);
> > +	if (ret) {
> > +		hdcp->hdcp2_supported = false;
> > +		kfree(hdcp->port_data.streams);
> >  		return ret;
> > +	}
> >  
> >  	hdcp->shim = shim;
> >  	mutex_init(&hdcp->mutex);
> >  	INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work);
> >  	INIT_WORK(&hdcp->prop_work, intel_hdcp_prop_work);
> > -
> > -	if (is_hdcp2_supported(dev_priv))
> > -		intel_hdcp2_init(connector);
> >  	init_waitqueue_head(&hdcp->cp_irq_queue);
> >  
> >  	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;
> > @@ -1827,6 +1832,7 @@ 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
> > @@ -1838,8 +1844,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_HDCP_CONTENT_TYPE1) {
> >  		ret = _intel_hdcp_enable(connector);
> >  	}
> >  
> > @@ -1921,12 +1931,15 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
> >  
> >  	/*
> >  	 * Nothing to do if the state didn't change, or HDCP was activated since
> > -	 * the last commit
> > +	 * the last commit. And also no change in hdcp content type.
> >  	 */
> >  	if (old_cp == new_cp ||
> >  	    (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
> > -	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED))
> > -		return;
> > +	     new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) {
> > +		if (old_state->hdcp_content_type ==
> > +				new_state->hdcp_content_type)
> > +			return;
> > +	}
> >  
> >  	crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
> >  						   new_state->crtc);
> > diff --git a/drivers/gpu/drm/i915/intel_hdcp.h b/drivers/gpu/drm/i915/intel_hdcp.h
> > index be8da85c866a..13555b054930 100644
> > --- a/drivers/gpu/drm/i915/intel_hdcp.h
> > +++ b/drivers/gpu/drm/i915/intel_hdcp.h
> > @@ -21,7 +21,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);
> > -- 
> > 2.19.1
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 04/12] drm/i915: Attach content type property
  2019-04-23 11:17     ` Ramalingam C
@ 2019-04-23 12:10       ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-23 12:10 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Tue, Apr 23, 2019 at 1:15 PM Ramalingam C <ramalingam.c@intel.com> wrote:
>
> On 2019-04-23 at 10:11:48 +0200, Daniel Vetter wrote:
> > On Thu, Apr 18, 2019 at 02:27:57PM +0530, Ramalingam C wrote:
> > > 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.
> > >
> > > v2:
> > >   s/cp_content_type/content_protection_type [daniel]
> > >   disable at hdcp_atomic_check to avoid check at atomic_set_property
> > >     [Maarten]
> > > v3:
> > >   s/content_protection_type/hdcp_content_type [Pekka]
> > > v4:
> > >   hdcp disable incase of type change is moved into commit [daniel].
> > >
> > > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > > ---
> > >  drivers/gpu/drm/i915/intel_ddi.c  | 38 ++++++++++++++++++++++++---
> > >  drivers/gpu/drm/i915/intel_hdcp.c | 43 ++++++++++++++++++++-----------
> > >  drivers/gpu/drm/i915/intel_hdcp.h |  2 +-
> > >  3 files changed, 63 insertions(+), 20 deletions(-)
> > >
> > > diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
> > > index 24f9106efcc6..dd9bea840937 100644
> > > --- a/drivers/gpu/drm/i915/intel_ddi.c
> > > +++ b/drivers/gpu/drm/i915/intel_ddi.c
> > > @@ -3476,7 +3476,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->hdcp_content_type);
> > >  }
> > >
> > >  static void intel_disable_ddi_dp(struct intel_encoder *encoder,
> > > @@ -3545,15 +3546,44 @@ static void intel_ddi_update_pipe(struct intel_encoder *encoder,
> > >                               const struct intel_crtc_state *crtc_state,
> > >                               const struct drm_connector_state *conn_state)
> > >  {
> > > +   struct intel_connector *connector =
> > > +                           to_intel_connector(conn_state->connector);
> > > +   struct intel_hdcp *hdcp = &connector->hdcp;
> > > +   bool  re_enable_hdcp = false;
> > > +   int ret = -EINVAL;
> > > +
> > >     if (!intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
> > >             intel_ddi_update_pipe_dp(encoder, crtc_state, conn_state);
> > >
> > > +   /*
> > > +    * During the HDCP encryption session if Type change is requested,
> > > +    * disable the HDCP and reenable it with new TYPE value.
> > > +    */
> > >     if (conn_state->content_protection ==
> > > -       DRM_MODE_CONTENT_PROTECTION_DESIRED)
> > > -           intel_hdcp_enable(to_intel_connector(conn_state->connector));
> > > +       DRM_MODE_CONTENT_PROTECTION_ENABLED &&
> > > +       conn_state->hdcp_content_type != hdcp->content_type) {
> > > +           intel_hdcp_disable(to_intel_connector(conn_state->connector));
> > > +           re_enable_hdcp = true;
> > > +   }
> > > +
> > > +   if (conn_state->content_protection ==
> > > +       DRM_MODE_CONTENT_PROTECTION_DESIRED || re_enable_hdcp)
> > > +           ret = intel_hdcp_enable(connector,
> > > +                                   (u8)conn_state->hdcp_content_type);
> > >     else if (conn_state->content_protection ==
> > >              DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> > > -           intel_hdcp_disable(to_intel_connector(conn_state->connector));
> > > +           intel_hdcp_disable(connector);
> > > +
> > > +   /*
> > > +    * During Type change handling re-enabling of the HDCP failed. Hence
> > > +    * changes state as ENABLED->DESIRED.
> > > +    */
> > > +   if (ret && re_enable_hdcp) {
> > > +           mutex_lock(&hdcp->mutex);
> > > +           hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> > > +           schedule_work(&hdcp->prop_work);
> > > +           mutex_unlock(&hdcp->mutex);
> > > +   }
> >
> > I'm unhappy with the convoluted logic here. It's correct I think but
> > fairly hard to follow. What about this instead?
> >
> >       unsigned int content_protection = conn_state->content_protection;
> >       bool content_protection_type_changed =
> >               conn_state->hdcp_content_type != hdcp->content_type;
> >
> >       if (conn_state->content_protection ==
> >                DRM_MODE_CONTENT_PROTECTION_UNDESIRED ||
> >           content_protection_type_changed)
> >               intel_hdcp_disable(to_intel_connector(conn_state->connector));
> >
> >       /* Make sure we pick up type changes */
> >       if (content_protection_type_changed) {
> >               mutex_lock(&hdcp->mutex);
> >               hdcp->value = DRM_MODE_CONTENT_PROTECTION_DESIRED;
> >               schedule_work(&hdcp->prop_work);
> >               mutex_unlock(&hdcp->mutex);
> >       }
> >
> >       if (conn_state->content_protection ==
> >           DRM_MODE_CONTENT_PROTECTION_DESIRED ||
> >           content_protection_type_changed)
> >               intel_hdcp_enable(to_intel_connector(conn_state->connector));
> >
> > Idea is to only have one disable and one enable call, and make sure the
> > enable picks up our content type change no matter what. But not sure that
> > it's really clearer. Thoughts?
> Sure. More simplified. I will add your reviewed-by with this change to
> the patch. Thanks.

Yeah r-b: me with (assuming it checks out once you've implemented it too).
-Daniel

>
> - Ram
> >
> > Aside from this lgtm.
> > -Daniel
> >
> >
> > >  }
> > >
> > >  static void intel_ddi_set_fia_lane_count(struct intel_encoder *encoder,
> > > diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> > > index a61391d374e8..772974697b5a 100644
> > > --- a/drivers/gpu/drm/i915/intel_hdcp.c
> > > +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> > > @@ -1717,14 +1717,15 @@ static const struct component_ops i915_hdcp_component_ops = {
> > >     .unbind = i915_hdcp_component_unbind,
> > >  };
> > >
> > > -static inline int initialize_hdcp_port_data(struct intel_connector *connector)
> > > +static inline int initialize_hdcp_port_data(struct intel_connector *connector,
> > > +                                       const struct intel_hdcp_shim *shim)
> > >  {
> > >     struct intel_hdcp *hdcp = &connector->hdcp;
> > >     struct hdcp_port_data *data = &hdcp->port_data;
> > >
> > >     data->port = connector->encoder->port;
> > >     data->port_type = (u8)HDCP_PORT_TYPE_INTEGRATED;
> > > -   data->protocol = (u8)hdcp->shim->protocol;
> > > +   data->protocol = (u8)shim->protocol;
> > >
> > >     data->k = 1;
> > >     if (!data->streams)
> > > @@ -1774,12 +1775,13 @@ void intel_hdcp_component_init(struct drm_i915_private *dev_priv)
> > >     }
> > >  }
> > >
> > > -static void intel_hdcp2_init(struct intel_connector *connector)
> > > +static void intel_hdcp2_init(struct intel_connector *connector,
> > > +                        const struct intel_hdcp_shim *shim)
> > >  {
> > >     struct intel_hdcp *hdcp = &connector->hdcp;
> > >     int ret;
> > >
> > > -   ret = initialize_hdcp_port_data(connector);
> > > +   ret = initialize_hdcp_port_data(connector, shim);
> > >     if (ret) {
> > >             DRM_DEBUG_KMS("Mei hdcp data init failed\n");
> > >             return;
> > > @@ -1798,25 +1800,28 @@ int intel_hdcp_init(struct intel_connector *connector,
> > >     if (!shim)
> > >             return -EINVAL;
> > >
> > > +   if (is_hdcp2_supported(dev_priv))
> > > +           intel_hdcp2_init(connector, shim);
> > > +
> > >     ret =
> > >     drm_connector_attach_content_protection_property(&connector->base,
> > > -                                                    false);
> > > -   if (ret)
> > > +                                                    hdcp->hdcp2_supported);
> > > +   if (ret) {
> > > +           hdcp->hdcp2_supported = false;
> > > +           kfree(hdcp->port_data.streams);
> > >             return ret;
> > > +   }
> > >
> > >     hdcp->shim = shim;
> > >     mutex_init(&hdcp->mutex);
> > >     INIT_DELAYED_WORK(&hdcp->check_work, intel_hdcp_check_work);
> > >     INIT_WORK(&hdcp->prop_work, intel_hdcp_prop_work);
> > > -
> > > -   if (is_hdcp2_supported(dev_priv))
> > > -           intel_hdcp2_init(connector);
> > >     init_waitqueue_head(&hdcp->cp_irq_queue);
> > >
> > >     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;
> > > @@ -1827,6 +1832,7 @@ 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
> > > @@ -1838,8 +1844,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_HDCP_CONTENT_TYPE1) {
> > >             ret = _intel_hdcp_enable(connector);
> > >     }
> > >
> > > @@ -1921,12 +1931,15 @@ void intel_hdcp_atomic_check(struct drm_connector *connector,
> > >
> > >     /*
> > >      * Nothing to do if the state didn't change, or HDCP was activated since
> > > -    * the last commit
> > > +    * the last commit. And also no change in hdcp content type.
> > >      */
> > >     if (old_cp == new_cp ||
> > >         (old_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED &&
> > > -        new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED))
> > > -           return;
> > > +        new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED)) {
> > > +           if (old_state->hdcp_content_type ==
> > > +                           new_state->hdcp_content_type)
> > > +                   return;
> > > +   }
> > >
> > >     crtc_state = drm_atomic_get_new_crtc_state(new_state->state,
> > >                                                new_state->crtc);
> > > diff --git a/drivers/gpu/drm/i915/intel_hdcp.h b/drivers/gpu/drm/i915/intel_hdcp.h
> > > index be8da85c866a..13555b054930 100644
> > > --- a/drivers/gpu/drm/i915/intel_hdcp.h
> > > +++ b/drivers/gpu/drm/i915/intel_hdcp.h
> > > @@ -21,7 +21,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);
> > > --
> > > 2.19.1
> > >
> >
> > --
> > Daniel Vetter
> > Software Engineer, Intel Corporation
> > http://blog.ffwll.ch



-- 
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] 33+ messages in thread

* Re: [PATCH v5 05/12] drm: revocation check at drm subsystem
  2019-04-18  8:57 ` [PATCH v5 05/12] drm: revocation check at drm subsystem Ramalingam C
@ 2019-04-29  7:26   ` Daniel Vetter
  2019-04-29  7:30     ` Daniel Vetter
  0 siblings, 1 reply; 33+ messages in thread
From: Daniel Vetter @ 2019-04-29  7:26 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Thu, Apr 18, 2019 at 02:27:58PM +0530, Ramalingam C wrote:
> On every hdcp revocation check request SRM is read from fw file
> /lib/firmware/display_hdcp_srm.bin
> 
> SRM table is parsed and stored at drm_hdcp.c, with functions exported
> for the services for revocation check from drivers (which
> implements the HDCP authentication)
> 
> This patch handles the HDCP1.4 and 2.2 versions of SRM table.
> 
> v2:
>   moved the uAPI to request_firmware_direct() [Daniel]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Suggested-by: Daniel Vetter <daniel@ffwll.ch>
> ---
>  drivers/gpu/drm/Makefile       |   2 +-
>  drivers/gpu/drm/drm_hdcp.c     | 336 +++++++++++++++++++++++++++++++++

Please add an include stanza for this new file to
Documentation/gpu/drm-kms-helpers.rst, somewhere near the other dp/hdcp
related sink helpers.

>  drivers/gpu/drm/drm_internal.h |   4 +
>  drivers/gpu/drm/drm_sysfs.c    |   2 +
>  include/drm/drm_hdcp.h         |  36 ++++
>  5 files changed, 379 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/gpu/drm/drm_hdcp.c
> 
> diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> index 3d0c75cd687c..fe8400af2426 100644
> --- a/drivers/gpu/drm/Makefile
> +++ b/drivers/gpu/drm/Makefile
> @@ -19,7 +19,7 @@ drm-y       :=	drm_auth.o drm_bufs.o drm_cache.o \
>  		drm_plane.o drm_color_mgmt.o drm_print.o \
>  		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
>  		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
> -		drm_atomic_uapi.o
> +		drm_atomic_uapi.o drm_hdcp.o
>  
>  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
>  drm-$(CONFIG_DRM_VM) += drm_vm.o
> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> new file mode 100644
> index 000000000000..78b043c8195e
> --- /dev/null
> +++ b/drivers/gpu/drm/drm_hdcp.c
> @@ -0,0 +1,336 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2019 Intel Corporation.
> + *
> + * Authors:
> + * Ramalingam C <ramalingam.c@intel.com>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/gfp.h>
> +#include <linux/export.h>
> +#include <linux/slab.h>
> +#include <linux/firmware.h>
> +
> +#include <drm/drm_hdcp.h>
> +#include <drm/drm_sysfs.h>
> +#include <drm/drm_print.h>
> +#include <drm/drm_device.h>
> +
> +struct hdcp_srm {
> +	u8 *srm_buf;
> +	size_t received_srm_sz;
> +	u32 revocated_ksv_cnt;
> +	u8 *revocated_ksv_list;
> +
> +	/* Mutex to protect above struct member */
> +	struct mutex mutex;
> +} *srm_data;
> +
> +static inline void drm_hdcp_print_ksv(const char *ksv)
> +{
> +	DRM_DEBUG("\t%#04x, %#04x, %#04x, %#04x, %#04x\n", *ksv & 0xff,

Why 04? 8 bit only needs 02 I think.

> +		  *(ksv + 1) & 0xff, *(ksv + 2) & 0xff, *(ksv + 3) & 0xff,
> +		  *(ksv + 4) & 0xff);

The 0xff is redundant, char is always only 8 bits. You could also simplify
the array derefe using ksv[0], ksv[1], ... it's the same expression.

Another one: There's a bit a confusion between const char * and u8* for
parsing the buffer. I think it'd be good to standardize on const u8* for
everything. I think that should also remove the need for 0xff completely,
because no more sign extensions to the full int.

> +}
> +
> +static u32 drm_hdcp_get_revocated_ksv_count(const char *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);

Hm, if we overflow here (i.e. parsed_bytes > vrls_lenght) then we return
garbage, since we already incremented ksv_count. Plus there's no error
checking of this. Kernel shouldn't trust root this much, and if the
vrls_length and our ksv parsing don't agree, we should abort the srm load.
So maybe switch the return value to int, and on error return -EINVAL and
abort?

> +
> +	return ksv_count;
> +}
> +
> +static u32 drm_hdcp_get_revocated_ksvs(const char *buf, u8 *revocated_ksv_list,
> +				       u32 vrls_length)

This function here doesn't need to be paranoid, since we already checked
the SRM by this point.

> +{
> +	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("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
> +			  vrl_ksv_cnt);
> +		memcpy(revocated_ksv_list, buf, vrl_ksv_sz);
> +
> +		ksv_count += vrl_ksv_cnt;
> +		revocated_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 drm_hdcp_parse_hdcp1_srm(const char *buf, size_t count)
> +{
> +	struct hdcp_srm_header *header;
> +	u32 vrl_length, ksv_count;
> +
> +	if (count < (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 *)buf;
> +	mutex_lock(&srm_data->mutex);
> +	DRM_DEBUG("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");
> +		mutex_unlock(&srm_data->mutex);
> +		return -EINVAL;
> +	}
> +
> +	buf = buf + sizeof(*header);
> +	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));

Maybe a static inline to implement this and use in the hdcp2 version below
too. Also I think buf[0], buf[1] is easier to read (as a bikeshed again).

> +	if (count < (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");
> +		mutex_unlock(&srm_data->mutex);
> +		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_ERROR("No vrl found\n");
> +		mutex_unlock(&srm_data->mutex);
> +		return -EINVAL;
> +	}
> +
> +	buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
> +	ksv_count = drm_hdcp_get_revocated_ksv_count(buf, vrl_length);
> +	if (!ksv_count) {
> +		DRM_DEBUG("Revocated KSV count is 0\n");
> +		mutex_unlock(&srm_data->mutex);
> +		return count;
> +	}
> +
> +	kfree(srm_data->revocated_ksv_list);
> +	srm_data->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
> +					       GFP_KERNEL);

kcalloc()

> +	if (!srm_data->revocated_ksv_list) {
> +		DRM_ERROR("Out of Memory\n");
> +		mutex_unlock(&srm_data->mutex);
> +		return -ENOMEM;
> +	}
> +
> +	if (drm_hdcp_get_revocated_ksvs(buf, srm_data->revocated_ksv_list,
> +					vrl_length) != ksv_count) {
> +		srm_data->revocated_ksv_cnt = 0;
> +		kfree(srm_data->revocated_ksv_list);
> +		mutex_unlock(&srm_data->mutex);
> +		return -EINVAL;
> +	}
> +
> +	srm_data->revocated_ksv_cnt = ksv_count;
> +	mutex_unlock(&srm_data->mutex);
> +	return count;
> +}
> +
> +static int drm_hdcp_parse_hdcp2_srm(const char *buf, size_t count)
> +{
> +	struct hdcp2_srm_header *header;
> +	u32 vrl_length, ksv_count, ksv_sz;
> +
> +	mutex_lock(&srm_data->mutex);
> +	if (count < (sizeof(struct hdcp2_srm_header) +
> +	    DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) {
> +		DRM_ERROR("Invalid blob length\n");
> +		mutex_unlock(&srm_data->mutex);
> +		return -EINVAL;
> +	}
> +
> +	header = (struct hdcp2_srm_header *)buf;
> +	DRM_DEBUG("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);
> +
> +	if (header->spec_indicator.reserved)
> +		return -EINVAL;
> +
> +	buf = buf + sizeof(*header);
> +	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));
> +
> +	if (count < (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");
> +		mutex_unlock(&srm_data->mutex);
> +		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");
> +		mutex_unlock(&srm_data->mutex);
> +		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) {
> +		DRM_DEBUG("Revocated KSV count is 0\n");
> +		mutex_unlock(&srm_data->mutex);
> +		return count;
> +	}
> +
> +	kfree(srm_data->revocated_ksv_list);
> +	srm_data->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
> +					       GFP_KERNEL);
> +	if (!srm_data->revocated_ksv_list) {
> +		DRM_ERROR("Out of Memory\n");
> +		mutex_unlock(&srm_data->mutex);
> +		return -ENOMEM;
> +	}
> +
> +	ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
> +	buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
> +
> +	DRM_DEBUG("Revoked KSVs: %d\n", ksv_count);
> +	memcpy(srm_data->revocated_ksv_list, buf, ksv_sz);
> +
> +	srm_data->revocated_ksv_cnt = ksv_count;
> +	mutex_unlock(&srm_data->mutex);
> +	return count;
> +}
> +
> +static inline bool is_srm_version_hdcp1(const char *buf)
> +{
> +	return ((u8)*buf) == DRM_HDCP_1_4_SRM_ID << 4;
> +}
> +
> +static inline bool is_srm_version_hdcp2(const char *buf)
> +{
> +	return ((u8)*buf) == (DRM_HDCP_2_SRM_ID << 4 |
> +			     DRM_HDCP_2_INDICATOR);
> +}
> +
> +static ssize_t drm_hdcp_srm_update(const char *buf, size_t count)
> +{
> +	if (is_srm_version_hdcp1(buf))
> +		return (ssize_t)drm_hdcp_parse_hdcp1_srm(buf, count);
> +	else if (is_srm_version_hdcp2(buf))
> +		return (ssize_t)drm_hdcp_parse_hdcp2_srm(buf, count);
> +
> +	return (ssize_t)-EINVAL;
> +}
> +
> +void drm_hdcp_request_srm(struct drm_device *drm_dev)
> +{
> +	char fw_name[36] = "display_hdcp_srm.bin";
> +	const struct firmware *fw;
> +
> +	int ret;
> +
> +	ret = request_firmware_direct(&fw, (const char *)fw_name,
> +				      drm_dev->dev);

We need an ack from Matt Roper or someont else from iotg on this.

> +	if (ret < 0)
> +		goto exit;
> +
> +	if (fw->size && fw->data)
> +		drm_hdcp_srm_update((const char *)fw->data, fw->size);
> +
> +exit:
> +	release_firmware(fw);
> +}
> +
> +/* Check if any of the KSV is revocated by DCP LLC through SRM table */
> +bool drm_hdcp_ksvs_revocated(struct drm_device *drm_dev, u8 *ksvs,

Since comment says "check", maybe put that into the function name? I like
to have verbs in function names that do something (instead of simple
helper functions to extract a computation to make the code a bit more
readable).

Also needs some nice kerneldoc.

> +			     u32 ksv_count)
> +{
> +	u32 rev_ksv_cnt, cnt, i, j;
> +	u8 *rev_ksv_list;
> +
> +	if (!srm_data)
> +		return false;
> +
> +	drm_hdcp_request_srm(drm_dev);
> +
> +	mutex_lock(&srm_data->mutex);

I'd have wrapped the locking around the entire function, should simplify
things a lot. Or does that anger lockdep when we call into
request_firmware()?

> +	rev_ksv_cnt = srm_data->revocated_ksv_cnt;
> +	rev_ksv_list = srm_data->revocated_ksv_list;
> +
> +	/* If the Revocated ksv list is empty */
> +	if (!rev_ksv_cnt || !rev_ksv_list) {
> +		mutex_unlock(&srm_data->mutex);
> +		return false;
> +	}
> +
> +	for  (cnt = 0; cnt < ksv_count; cnt++) {
> +		rev_ksv_list = srm_data->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("Revocated KSV is ");
> +					drm_hdcp_print_ksv(ksvs);
> +					mutex_unlock(&srm_data->mutex);
> +					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;
> +	}
> +	mutex_unlock(&srm_data->mutex);
> +	return false;
> +}
> +EXPORT_SYMBOL_GPL(drm_hdcp_ksvs_revocated);
> +
> +int drm_setup_hdcp_srm(struct class *drm_class)
> +{
> +	srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
> +	if (!srm_data)
> +		return -ENOMEM;
> +
> +	srm_data->srm_buf = kcalloc(DRM_HDCP_SRM_GEN1_MAX_BYTES,
> +				    sizeof(u8), GFP_KERNEL);
> +	if (!srm_data->srm_buf) {
> +		kfree(srm_data);
> +		return -ENOMEM;
> +	}
> +	mutex_init(&srm_data->mutex);
> +
> +	return 0;
> +}
> +
> +void drm_teardown_hdcp_srm(struct class *drm_class)
> +{
> +	if (srm_data) {
> +		kfree(srm_data->srm_buf);
> +		kfree(srm_data->revocated_ksv_list);
> +		kfree(srm_data);
> +	}
> +}
> diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> index d9a483a5fce0..ef3180443870 100644
> --- a/drivers/gpu/drm/drm_internal.h
> +++ b/drivers/gpu/drm/drm_internal.h
> @@ -199,3 +199,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
>  void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
>  				const struct drm_framebuffer *fb);
>  int drm_framebuffer_debugfs_init(struct drm_minor *minor);
> +
> +/* drm_hdcp.c */
> +int drm_setup_hdcp_srm(struct class *drm_class);
> +void drm_teardown_hdcp_srm(struct class *drm_class);
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index ecb7b33002bb..18b1ac442997 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -78,6 +78,7 @@ int drm_sysfs_init(void)
>  	}
>  
>  	drm_class->devnode = drm_devnode;
> +	drm_setup_hdcp_srm(drm_class);
>  	return 0;
>  }
>  
> @@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)
>  {
>  	if (IS_ERR_OR_NULL(drm_class))
>  		return;
> +	drm_teardown_hdcp_srm(drm_class);
>  	class_remove_file(drm_class, &class_attr_version.attr);
>  	class_destroy(drm_class);
>  	drm_class = NULL;
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index f243408ecf26..ff2bcfc1ecef 100644
> --- a/include/drm/drm_hdcp.h
> +++ b/include/drm/drm_hdcp.h
> @@ -265,4 +265,40 @@ 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_SRM_GEN1_MAX_BYTES		(5 * 1024)
> +#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;

bitfields in binary structures are heavily discouraged. I think since this
is only u8 it should be fine, but explaining that is more work than just
having the usual _MASK/_SHIFT #defines like we do with registers.

> +		u8 reserved_lo;
> +	} spec_indicator;

If you wannt __packed, you also need to list this to sub-structs.

> +	u16 srm_version;
> +	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)
> +
> +struct hdcp2_srm_header {
> +	struct {
> +		u8 hdcp2_indicator:4;

Since hdcp1/2 match except for this I think better to merge them.

> +		u8 srm_id:4;
> +		u8 reserved;
> +	} spec_indicator;
> +	u16 srm_version;
> +	u8 srm_gen_no;
> +} __packed;
> +
> +struct drm_device;
> +
> +bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
>  #endif

Cheers, Daniel

> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
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] 33+ messages in thread

* Re: [PATCH v5 06/12] drm/i915: SRM revocation check for HDCP1.4 and 2.2
  2019-04-18  8:57 ` [PATCH v5 06/12] drm/i915: SRM revocation check for HDCP1.4 and 2.2 Ramalingam C
@ 2019-04-29  7:28   ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-29  7:28 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel, gwan-gyeong.mun

On Thu, Apr 18, 2019 at 02:27:59PM +0530, Ramalingam C wrote:
> DRM HDCP SRM revocation check services are used from I915 for HDCP1.4
> and 2.2 revocation check during the respective authentication flow.
> 
> v2:
>   Rebased.
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/i915/intel_hdcp.c | 57 ++++++++++++++++++++++++-------
>  1 file changed, 44 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> index 772974697b5a..de634f3fbd1b 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -492,9 +492,11 @@ 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_connector *connector)
>  {
> +	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
> +	const struct intel_hdcp_shim *shim = connector->hdcp.shim;
> +	struct drm_device *dev = connector->base.dev;
>  	u8 bstatus[2], num_downstream, *ksv_fifo;
>  	int ret, i, tries = 3;
>  
> @@ -533,6 +535,11 @@ int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port,
>  	if (ret)
>  		goto err;
>  
> +	if (drm_hdcp_ksvs_revocated(dev, 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.
> @@ -559,9 +566,12 @@ 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;
> +	struct drm_device *dev = connector->base.dev;
> +	const struct intel_hdcp_shim *shim = hdcp->shim;
>  	struct drm_i915_private *dev_priv;
>  	enum port port;
>  	unsigned long r0_prime_gen_start;
> @@ -627,6 +637,11 @@ static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port,
>  	if (ret < 0)
>  		return ret;
>  
> +	if (drm_hdcp_ksvs_revocated(dev, 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]);
>  
> @@ -700,7 +715,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(connector);
>  
>  	DRM_DEBUG_KMS("HDCP is enabled (no repeater present)\n");
>  	return 0;
> @@ -763,7 +778,7 @@ 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;
>  			return 0;
> @@ -779,12 +794,6 @@ static int _intel_hdcp_enable(struct intel_connector *connector)
>  	return ret;
>  }
>  
> -static inline
> -struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
> -{
> -	return container_of(hdcp, struct intel_connector, hdcp);
> -}
> -
>  /* Implements Part 3 of the HDCP authorization procedure */
>  static int intel_hdcp_check_link(struct intel_connector *connector)
>  {
> @@ -845,6 +854,12 @@ static int intel_hdcp_check_link(struct intel_connector *connector)
>  	return ret;
>  }
>  
> +static inline
> +struct intel_connector *intel_hdcp_to_connector(struct intel_hdcp *hdcp)
> +{
> +	return container_of(hdcp, struct intel_connector, hdcp);
> +}

Moving intel_hdcp_to_connector around doesn't seem to be necessary?

> +
>  static void intel_hdcp_prop_work(struct work_struct *work)
>  {
>  	struct intel_hdcp *hdcp = container_of(work, struct intel_hdcp,
> @@ -1162,6 +1177,7 @@ static int hdcp2_authentication_key_exchange(struct intel_connector *connector)
>  {
>  	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
> +	struct drm_device *dev = connector->base.dev;
>  	union {
>  		struct hdcp2_ake_init ake_init;
>  		struct hdcp2_ake_send_cert send_cert;
> @@ -1196,6 +1212,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 (drm_hdcp_ksvs_revocated(dev,
> +				    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.
> @@ -1348,13 +1370,14 @@ int hdcp2_authenticate_repeater_topology(struct intel_connector *connector)
>  {
>  	struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector);
>  	struct intel_hdcp *hdcp = &connector->hdcp;
> +	struct drm_device *dev = connector->base.dev;
>  	union {
>  		struct hdcp2_rep_send_receiverid_list recvid_list;
>  		struct hdcp2_rep_send_ack rep_ack;
>  	} msgs;
>  	const struct intel_hdcp_shim *shim = hdcp->shim;
> +	u32 seq_num_v, device_cnt;
>  	u8 *rx_info;
> -	u32 seq_num_v;
>  	int ret;
>  
>  	ret = shim->read_2_2_msg(intel_dig_port, HDCP_2_2_REP_SEND_RECVID_LIST,
> @@ -1379,6 +1402,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 (drm_hdcp_ksvs_revocated(dev, 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);
> -- 
> 2.19.1

Aside from the nit lgtm, with that hunk removed:

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

Plus might need to adjust to drm_hdcp_check_ksvs_revoked.
-Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 05/12] drm: revocation check at drm subsystem
  2019-04-29  7:26   ` Daniel Vetter
@ 2019-04-29  7:30     ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-29  7:30 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel, gwan-gyeong.mun

On Mon, Apr 29, 2019 at 09:26:07AM +0200, Daniel Vetter wrote:
> On Thu, Apr 18, 2019 at 02:27:58PM +0530, Ramalingam C wrote:
> > On every hdcp revocation check request SRM is read from fw file
> > /lib/firmware/display_hdcp_srm.bin
> > 
> > SRM table is parsed and stored at drm_hdcp.c, with functions exported
> > for the services for revocation check from drivers (which
> > implements the HDCP authentication)
> > 
> > This patch handles the HDCP1.4 and 2.2 versions of SRM table.
> > 
> > v2:
> >   moved the uAPI to request_firmware_direct() [Daniel]
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > Suggested-by: Daniel Vetter <daniel@ffwll.ch>
> > ---
> >  drivers/gpu/drm/Makefile       |   2 +-
> >  drivers/gpu/drm/drm_hdcp.c     | 336 +++++++++++++++++++++++++++++++++
> 
> Please add an include stanza for this new file to
> Documentation/gpu/drm-kms-helpers.rst, somewhere near the other dp/hdcp
> related sink helpers.
> 
> >  drivers/gpu/drm/drm_internal.h |   4 +
> >  drivers/gpu/drm/drm_sysfs.c    |   2 +
> >  include/drm/drm_hdcp.h         |  36 ++++
> >  5 files changed, 379 insertions(+), 1 deletion(-)
> >  create mode 100644 drivers/gpu/drm/drm_hdcp.c
> > 
> > diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
> > index 3d0c75cd687c..fe8400af2426 100644
> > --- a/drivers/gpu/drm/Makefile
> > +++ b/drivers/gpu/drm/Makefile
> > @@ -19,7 +19,7 @@ drm-y       :=	drm_auth.o drm_bufs.o drm_cache.o \
> >  		drm_plane.o drm_color_mgmt.o drm_print.o \
> >  		drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \
> >  		drm_syncobj.o drm_lease.o drm_writeback.o drm_client.o \
> > -		drm_atomic_uapi.o
> > +		drm_atomic_uapi.o drm_hdcp.o
> >  
> >  drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o
> >  drm-$(CONFIG_DRM_VM) += drm_vm.o
> > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > new file mode 100644
> > index 000000000000..78b043c8195e
> > --- /dev/null
> > +++ b/drivers/gpu/drm/drm_hdcp.c
> > @@ -0,0 +1,336 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Copyright (C) 2019 Intel Corporation.
> > + *
> > + * Authors:
> > + * Ramalingam C <ramalingam.c@intel.com>
> > + */
> > +
> > +#include <linux/device.h>
> > +#include <linux/err.h>
> > +#include <linux/gfp.h>
> > +#include <linux/export.h>
> > +#include <linux/slab.h>
> > +#include <linux/firmware.h>
> > +
> > +#include <drm/drm_hdcp.h>
> > +#include <drm/drm_sysfs.h>
> > +#include <drm/drm_print.h>
> > +#include <drm/drm_device.h>
> > +
> > +struct hdcp_srm {
> > +	u8 *srm_buf;
> > +	size_t received_srm_sz;
> > +	u32 revocated_ksv_cnt;
> > +	u8 *revocated_ksv_list;

So not sure this is from the standard or not, but my dictionary says the
verb is revoke, not revocate. Please change everywhere from revocated to
revoked.

So drm_hdcp_check_ksvs_revoked() for the one exported function.
-Daniel


> > +
> > +	/* Mutex to protect above struct member */
> > +	struct mutex mutex;
> > +} *srm_data;
> > +
> > +static inline void drm_hdcp_print_ksv(const char *ksv)
> > +{
> > +	DRM_DEBUG("\t%#04x, %#04x, %#04x, %#04x, %#04x\n", *ksv & 0xff,
> 
> Why 04? 8 bit only needs 02 I think.
> 
> > +		  *(ksv + 1) & 0xff, *(ksv + 2) & 0xff, *(ksv + 3) & 0xff,
> > +		  *(ksv + 4) & 0xff);
> 
> The 0xff is redundant, char is always only 8 bits. You could also simplify
> the array derefe using ksv[0], ksv[1], ... it's the same expression.
> 
> Another one: There's a bit a confusion between const char * and u8* for
> parsing the buffer. I think it'd be good to standardize on const u8* for
> everything. I think that should also remove the need for 0xff completely,
> because no more sign extensions to the full int.
> 
> > +}
> > +
> > +static u32 drm_hdcp_get_revocated_ksv_count(const char *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);
> 
> Hm, if we overflow here (i.e. parsed_bytes > vrls_lenght) then we return
> garbage, since we already incremented ksv_count. Plus there's no error
> checking of this. Kernel shouldn't trust root this much, and if the
> vrls_length and our ksv parsing don't agree, we should abort the srm load.
> So maybe switch the return value to int, and on error return -EINVAL and
> abort?
> 
> > +
> > +	return ksv_count;
> > +}
> > +
> > +static u32 drm_hdcp_get_revocated_ksvs(const char *buf, u8 *revocated_ksv_list,
> > +				       u32 vrls_length)
> 
> This function here doesn't need to be paranoid, since we already checked
> the SRM by this point.
> 
> > +{
> > +	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("vrl: %d, Revoked KSVs: %d\n", vrl_idx++,
> > +			  vrl_ksv_cnt);
> > +		memcpy(revocated_ksv_list, buf, vrl_ksv_sz);
> > +
> > +		ksv_count += vrl_ksv_cnt;
> > +		revocated_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 drm_hdcp_parse_hdcp1_srm(const char *buf, size_t count)
> > +{
> > +	struct hdcp_srm_header *header;
> > +	u32 vrl_length, ksv_count;
> > +
> > +	if (count < (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 *)buf;
> > +	mutex_lock(&srm_data->mutex);
> > +	DRM_DEBUG("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");
> > +		mutex_unlock(&srm_data->mutex);
> > +		return -EINVAL;
> > +	}
> > +
> > +	buf = buf + sizeof(*header);
> > +	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));
> 
> Maybe a static inline to implement this and use in the hdcp2 version below
> too. Also I think buf[0], buf[1] is easier to read (as a bikeshed again).
> 
> > +	if (count < (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");
> > +		mutex_unlock(&srm_data->mutex);
> > +		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_ERROR("No vrl found\n");
> > +		mutex_unlock(&srm_data->mutex);
> > +		return -EINVAL;
> > +	}
> > +
> > +	buf += DRM_HDCP_1_4_VRL_LENGTH_SIZE;
> > +	ksv_count = drm_hdcp_get_revocated_ksv_count(buf, vrl_length);
> > +	if (!ksv_count) {
> > +		DRM_DEBUG("Revocated KSV count is 0\n");
> > +		mutex_unlock(&srm_data->mutex);
> > +		return count;
> > +	}
> > +
> > +	kfree(srm_data->revocated_ksv_list);
> > +	srm_data->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
> > +					       GFP_KERNEL);
> 
> kcalloc()
> 
> > +	if (!srm_data->revocated_ksv_list) {
> > +		DRM_ERROR("Out of Memory\n");
> > +		mutex_unlock(&srm_data->mutex);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	if (drm_hdcp_get_revocated_ksvs(buf, srm_data->revocated_ksv_list,
> > +					vrl_length) != ksv_count) {
> > +		srm_data->revocated_ksv_cnt = 0;
> > +		kfree(srm_data->revocated_ksv_list);
> > +		mutex_unlock(&srm_data->mutex);
> > +		return -EINVAL;
> > +	}
> > +
> > +	srm_data->revocated_ksv_cnt = ksv_count;
> > +	mutex_unlock(&srm_data->mutex);
> > +	return count;
> > +}
> > +
> > +static int drm_hdcp_parse_hdcp2_srm(const char *buf, size_t count)
> > +{
> > +	struct hdcp2_srm_header *header;
> > +	u32 vrl_length, ksv_count, ksv_sz;
> > +
> > +	mutex_lock(&srm_data->mutex);
> > +	if (count < (sizeof(struct hdcp2_srm_header) +
> > +	    DRM_HDCP_2_VRL_LENGTH_SIZE + DRM_HDCP_2_DCP_SIG_SIZE)) {
> > +		DRM_ERROR("Invalid blob length\n");
> > +		mutex_unlock(&srm_data->mutex);
> > +		return -EINVAL;
> > +	}
> > +
> > +	header = (struct hdcp2_srm_header *)buf;
> > +	DRM_DEBUG("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);
> > +
> > +	if (header->spec_indicator.reserved)
> > +		return -EINVAL;
> > +
> > +	buf = buf + sizeof(*header);
> > +	vrl_length = (*buf << 16 | *(buf + 1) << 8 | *(buf + 2));
> > +
> > +	if (count < (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");
> > +		mutex_unlock(&srm_data->mutex);
> > +		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");
> > +		mutex_unlock(&srm_data->mutex);
> > +		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) {
> > +		DRM_DEBUG("Revocated KSV count is 0\n");
> > +		mutex_unlock(&srm_data->mutex);
> > +		return count;
> > +	}
> > +
> > +	kfree(srm_data->revocated_ksv_list);
> > +	srm_data->revocated_ksv_list = kzalloc(ksv_count * DRM_HDCP_KSV_LEN,
> > +					       GFP_KERNEL);
> > +	if (!srm_data->revocated_ksv_list) {
> > +		DRM_ERROR("Out of Memory\n");
> > +		mutex_unlock(&srm_data->mutex);
> > +		return -ENOMEM;
> > +	}
> > +
> > +	ksv_sz = ksv_count * DRM_HDCP_KSV_LEN;
> > +	buf += DRM_HDCP_2_NO_OF_DEV_PLUS_RESERVED_SZ;
> > +
> > +	DRM_DEBUG("Revoked KSVs: %d\n", ksv_count);
> > +	memcpy(srm_data->revocated_ksv_list, buf, ksv_sz);
> > +
> > +	srm_data->revocated_ksv_cnt = ksv_count;
> > +	mutex_unlock(&srm_data->mutex);
> > +	return count;
> > +}
> > +
> > +static inline bool is_srm_version_hdcp1(const char *buf)
> > +{
> > +	return ((u8)*buf) == DRM_HDCP_1_4_SRM_ID << 4;
> > +}
> > +
> > +static inline bool is_srm_version_hdcp2(const char *buf)
> > +{
> > +	return ((u8)*buf) == (DRM_HDCP_2_SRM_ID << 4 |
> > +			     DRM_HDCP_2_INDICATOR);
> > +}
> > +
> > +static ssize_t drm_hdcp_srm_update(const char *buf, size_t count)
> > +{
> > +	if (is_srm_version_hdcp1(buf))
> > +		return (ssize_t)drm_hdcp_parse_hdcp1_srm(buf, count);
> > +	else if (is_srm_version_hdcp2(buf))
> > +		return (ssize_t)drm_hdcp_parse_hdcp2_srm(buf, count);
> > +
> > +	return (ssize_t)-EINVAL;
> > +}
> > +
> > +void drm_hdcp_request_srm(struct drm_device *drm_dev)
> > +{
> > +	char fw_name[36] = "display_hdcp_srm.bin";
> > +	const struct firmware *fw;
> > +
> > +	int ret;
> > +
> > +	ret = request_firmware_direct(&fw, (const char *)fw_name,
> > +				      drm_dev->dev);
> 
> We need an ack from Matt Roper or someont else from iotg on this.
> 
> > +	if (ret < 0)
> > +		goto exit;
> > +
> > +	if (fw->size && fw->data)
> > +		drm_hdcp_srm_update((const char *)fw->data, fw->size);
> > +
> > +exit:
> > +	release_firmware(fw);
> > +}
> > +
> > +/* Check if any of the KSV is revocated by DCP LLC through SRM table */
> > +bool drm_hdcp_ksvs_revocated(struct drm_device *drm_dev, u8 *ksvs,
> 
> Since comment says "check", maybe put that into the function name? I like
> to have verbs in function names that do something (instead of simple
> helper functions to extract a computation to make the code a bit more
> readable).
> 
> Also needs some nice kerneldoc.
> 
> > +			     u32 ksv_count)
> > +{
> > +	u32 rev_ksv_cnt, cnt, i, j;
> > +	u8 *rev_ksv_list;
> > +
> > +	if (!srm_data)
> > +		return false;
> > +
> > +	drm_hdcp_request_srm(drm_dev);
> > +
> > +	mutex_lock(&srm_data->mutex);
> 
> I'd have wrapped the locking around the entire function, should simplify
> things a lot. Or does that anger lockdep when we call into
> request_firmware()?
> 
> > +	rev_ksv_cnt = srm_data->revocated_ksv_cnt;
> > +	rev_ksv_list = srm_data->revocated_ksv_list;
> > +
> > +	/* If the Revocated ksv list is empty */
> > +	if (!rev_ksv_cnt || !rev_ksv_list) {
> > +		mutex_unlock(&srm_data->mutex);
> > +		return false;
> > +	}
> > +
> > +	for  (cnt = 0; cnt < ksv_count; cnt++) {
> > +		rev_ksv_list = srm_data->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("Revocated KSV is ");
> > +					drm_hdcp_print_ksv(ksvs);
> > +					mutex_unlock(&srm_data->mutex);
> > +					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;
> > +	}
> > +	mutex_unlock(&srm_data->mutex);
> > +	return false;
> > +}
> > +EXPORT_SYMBOL_GPL(drm_hdcp_ksvs_revocated);
> > +
> > +int drm_setup_hdcp_srm(struct class *drm_class)
> > +{
> > +	srm_data = kzalloc(sizeof(*srm_data), GFP_KERNEL);
> > +	if (!srm_data)
> > +		return -ENOMEM;
> > +
> > +	srm_data->srm_buf = kcalloc(DRM_HDCP_SRM_GEN1_MAX_BYTES,
> > +				    sizeof(u8), GFP_KERNEL);
> > +	if (!srm_data->srm_buf) {
> > +		kfree(srm_data);
> > +		return -ENOMEM;
> > +	}
> > +	mutex_init(&srm_data->mutex);
> > +
> > +	return 0;
> > +}
> > +
> > +void drm_teardown_hdcp_srm(struct class *drm_class)
> > +{
> > +	if (srm_data) {
> > +		kfree(srm_data->srm_buf);
> > +		kfree(srm_data->revocated_ksv_list);
> > +		kfree(srm_data);
> > +	}
> > +}
> > diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
> > index d9a483a5fce0..ef3180443870 100644
> > --- a/drivers/gpu/drm/drm_internal.h
> > +++ b/drivers/gpu/drm/drm_internal.h
> > @@ -199,3 +199,7 @@ int drm_syncobj_query_ioctl(struct drm_device *dev, void *data,
> >  void drm_framebuffer_print_info(struct drm_printer *p, unsigned int indent,
> >  				const struct drm_framebuffer *fb);
> >  int drm_framebuffer_debugfs_init(struct drm_minor *minor);
> > +
> > +/* drm_hdcp.c */
> > +int drm_setup_hdcp_srm(struct class *drm_class);
> > +void drm_teardown_hdcp_srm(struct class *drm_class);
> > diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> > index ecb7b33002bb..18b1ac442997 100644
> > --- a/drivers/gpu/drm/drm_sysfs.c
> > +++ b/drivers/gpu/drm/drm_sysfs.c
> > @@ -78,6 +78,7 @@ int drm_sysfs_init(void)
> >  	}
> >  
> >  	drm_class->devnode = drm_devnode;
> > +	drm_setup_hdcp_srm(drm_class);
> >  	return 0;
> >  }
> >  
> > @@ -90,6 +91,7 @@ void drm_sysfs_destroy(void)
> >  {
> >  	if (IS_ERR_OR_NULL(drm_class))
> >  		return;
> > +	drm_teardown_hdcp_srm(drm_class);
> >  	class_remove_file(drm_class, &class_attr_version.attr);
> >  	class_destroy(drm_class);
> >  	drm_class = NULL;
> > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> > index f243408ecf26..ff2bcfc1ecef 100644
> > --- a/include/drm/drm_hdcp.h
> > +++ b/include/drm/drm_hdcp.h
> > @@ -265,4 +265,40 @@ 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_SRM_GEN1_MAX_BYTES		(5 * 1024)
> > +#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;
> 
> bitfields in binary structures are heavily discouraged. I think since this
> is only u8 it should be fine, but explaining that is more work than just
> having the usual _MASK/_SHIFT #defines like we do with registers.
> 
> > +		u8 reserved_lo;
> > +	} spec_indicator;
> 
> If you wannt __packed, you also need to list this to sub-structs.
> 
> > +	u16 srm_version;
> > +	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)
> > +
> > +struct hdcp2_srm_header {
> > +	struct {
> > +		u8 hdcp2_indicator:4;
> 
> Since hdcp1/2 match except for this I think better to merge them.
> 
> > +		u8 srm_id:4;
> > +		u8 reserved;
> > +	} spec_indicator;
> > +	u16 srm_version;
> > +	u8 srm_gen_no;
> > +} __packed;
> > +
> > +struct drm_device;
> > +
> > +bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
> >  #endif
> 
> Cheers, Daniel
> 
> > -- 
> > 2.19.1
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> http://blog.ffwll.ch

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 07/12] drm/hdcp: gathering hdcp related code into drm_hdcp.c
  2019-04-18  8:58 ` [PATCH v5 07/12] drm/hdcp: gathering hdcp related code into drm_hdcp.c Ramalingam C
@ 2019-04-29  7:31   ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-29  7:31 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Thu, Apr 18, 2019 at 02:28:00PM +0530, Ramalingam C wrote:
> Considering the significant size of hdcp related code in drm, all
> hdcp related codes are moved into separate file called drm_hdcp.c.
> 
> v2:
>   Rebased.
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> Suggested-by: Daniel Vetter <daniel@ffwll.ch>
> ---
>  drivers/gpu/drm/drm_connector.c | 78 -------------------------------
>  drivers/gpu/drm/drm_hdcp.c      | 81 +++++++++++++++++++++++++++++++++

Need to make sure this is still included into
Documenation/gpu/drm-kms-helpers.rst. But an earlier patch should take
care of that, so

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

>  include/drm/drm_connector.h     |  2 -
>  include/drm/drm_hdcp.h          |  3 ++
>  4 files changed, 84 insertions(+), 80 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_connector.c b/drivers/gpu/drm/drm_connector.c
> index 03907d13ef66..436cf8e764cc 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -823,13 +823,6 @@ static const struct drm_prop_enum_list drm_tv_subconnector_enum_list[] = {
>  DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
>  		 drm_tv_subconnector_enum_list)
>  
> -static struct drm_prop_enum_list drm_cp_enum_list[] = {
> -	{ DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
> -	{ DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
> -	{ DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
> -};
> -DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
> -
>  static const struct drm_prop_enum_list hdmi_colorspaces[] = {
>  	/* For Default case, driver will set the colorspace */
>  	{ DRM_MODE_COLORIMETRY_DEFAULT, "Default" },
> @@ -857,13 +850,6 @@ 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_hdcp_content_type_enum_list[] = {
> -	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
> -	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
> -};
> -DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> -		 drm_hdcp_content_type_enum_list)
> -
>  /**
>   * DOC: standard connector properties
>   *
> @@ -1539,70 +1525,6 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
>  }
>  EXPORT_SYMBOL(drm_connector_attach_scaling_mode_property);
>  
> -/**
> - * drm_connector_attach_content_protection_property - attach content protection
> - * property
> - *
> - * @connector: connector to attach CP property on.
> - * @hdcp_content_type: is HDCP Content Type property needed for connector
> - *
> - * This is used to add support for content protection on select connectors.
> - * Content Protection is intentionally vague to allow for different underlying
> - * technologies, however it is most implemented by HDCP.
> - *
> - * When hdcp_content_type is true enum property called HDCP Content Type is
> - * created (if it is not already) and attached to the connector.
> - *
> - * This property is used for sending the protected content's stream type
> - * from userspace to kernel on selected connectors. Protected content provider
> - * will decide their type of their content and declare the same to kernel.
> - *
> - * Content type will be used during the HDCP 2.2 authentication.
> - * Content type will be set to &drm_connector_state.hdcp_content_type.
> - *
> - * The content protection will be set to &drm_connector_state.content_protection
> - *
> - * Returns:
> - * Zero on success, negative errno on failure.
> - */
> -int drm_connector_attach_content_protection_property(
> -		struct drm_connector *connector, bool hdcp_content_type)
> -{
> -	struct drm_device *dev = connector->dev;
> -	struct drm_property *prop =
> -			dev->mode_config.content_protection_property;
> -
> -	if (!prop)
> -		prop = drm_property_create_enum(dev, 0, "Content Protection",
> -						drm_cp_enum_list,
> -						ARRAY_SIZE(drm_cp_enum_list));
> -	if (!prop)
> -		return -ENOMEM;
> -
> -	drm_object_attach_property(&connector->base, prop,
> -				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
> -	dev->mode_config.content_protection_property = prop;
> -
> -	if (!hdcp_content_type)
> -		return 0;
> -
> -	prop = dev->mode_config.hdcp_content_type_property;
> -	if (!prop)
> -		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
> -					drm_hdcp_content_type_enum_list,
> -					ARRAY_SIZE(
> -					drm_hdcp_content_type_enum_list));
> -	if (!prop)
> -		return -ENOMEM;
> -
> -	drm_object_attach_property(&connector->base, prop,
> -				   DRM_MODE_HDCP_CONTENT_TYPE0);
> -	dev->mode_config.hdcp_content_type_property = prop;
> -
> -	return 0;
> -}
> -EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> -
>  /**
>   * drm_mode_create_aspect_ratio_property - create aspect ratio property
>   * @dev: DRM device
> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> index 78b043c8195e..a0960507e4ff 100644
> --- a/drivers/gpu/drm/drm_hdcp.c
> +++ b/drivers/gpu/drm/drm_hdcp.c
> @@ -17,6 +17,9 @@
>  #include <drm/drm_sysfs.h>
>  #include <drm/drm_print.h>
>  #include <drm/drm_device.h>
> +#include <drm/drm_property.h>
> +#include <drm/drm_mode_object.h>
> +#include <drm/drm_connector.h>
>  
>  struct hdcp_srm {
>  	u8 *srm_buf;
> @@ -334,3 +337,81 @@ void drm_teardown_hdcp_srm(struct class *drm_class)
>  		kfree(srm_data);
>  	}
>  }
> +
> +static struct drm_prop_enum_list drm_cp_enum_list[] = {
> +	{ DRM_MODE_CONTENT_PROTECTION_UNDESIRED, "Undesired" },
> +	{ DRM_MODE_CONTENT_PROTECTION_DESIRED, "Desired" },
> +	{ DRM_MODE_CONTENT_PROTECTION_ENABLED, "Enabled" },
> +};
> +DRM_ENUM_NAME_FN(drm_get_content_protection_name, drm_cp_enum_list)
> +
> +static struct drm_prop_enum_list drm_hdcp_content_type_enum_list[] = {
> +	{ DRM_MODE_HDCP_CONTENT_TYPE0, "HDCP Type0" },
> +	{ DRM_MODE_HDCP_CONTENT_TYPE1, "HDCP Type1" },
> +};
> +DRM_ENUM_NAME_FN(drm_get_hdcp_content_type_name,
> +		 drm_hdcp_content_type_enum_list)
> +
> +/**
> + * drm_connector_attach_content_protection_property - attach content protection
> + * property
> + *
> + * @connector: connector to attach CP property on.
> + * @hdcp_content_type: is HDCP Content Type property needed for connector
> + *
> + * This is used to add support for content protection on select connectors.
> + * Content Protection is intentionally vague to allow for different underlying
> + * technologies, however it is most implemented by HDCP.
> + *
> + * When hdcp_content_type is true enum property called HDCP Content Type is
> + * created (if it is not already) and attached to the connector.
> + *
> + * This property is used for sending the protected content's stream type
> + * from userspace to kernel on selected connectors. Protected content provider
> + * will decide their type of their content and declare the same to kernel.
> + *
> + * Content type will be used during the HDCP 2.2 authentication.
> + * Content type will be set to &drm_connector_state.hdcp_content_type.
> + *
> + * The content protection will be set to &drm_connector_state.content_protection
> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_connector_attach_content_protection_property(
> +		struct drm_connector *connector, bool hdcp_content_type)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct drm_property *prop =
> +			dev->mode_config.content_protection_property;
> +
> +	if (!prop)
> +		prop = drm_property_create_enum(dev, 0, "Content Protection",
> +						drm_cp_enum_list,
> +						ARRAY_SIZE(drm_cp_enum_list));
> +	if (!prop)
> +		return -ENOMEM;
> +
> +	drm_object_attach_property(&connector->base, prop,
> +				   DRM_MODE_CONTENT_PROTECTION_UNDESIRED);
> +	dev->mode_config.content_protection_property = prop;
> +
> +	if (!hdcp_content_type)
> +		return 0;
> +
> +	prop = dev->mode_config.hdcp_content_type_property;
> +	if (!prop)
> +		prop = drm_property_create_enum(dev, 0, "HDCP Content Type",
> +					drm_hdcp_content_type_enum_list,
> +					ARRAY_SIZE(
> +					drm_hdcp_content_type_enum_list));
> +	if (!prop)
> +		return -ENOMEM;
> +
> +	drm_object_attach_property(&connector->base, prop,
> +				   DRM_MODE_HDCP_CONTENT_TYPE0);
> +	dev->mode_config.hdcp_content_type_property = prop;
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 2d2c2d5e7681..9e2f1a9de2a0 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -1346,8 +1346,6 @@ int drm_connector_attach_scaling_mode_property(struct drm_connector *connector,
>  					       u32 scaling_mode_mask);
>  int drm_connector_attach_vrr_capable_property(
>  		struct drm_connector *connector);
> -int drm_connector_attach_content_protection_property(
> -		struct drm_connector *connector, bool hdcp_content_type);
>  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/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index ff2bcfc1ecef..145c81ba1e09 100644
> --- a/include/drm/drm_hdcp.h
> +++ b/include/drm/drm_hdcp.h
> @@ -299,6 +299,9 @@ struct hdcp2_srm_header {
>  } __packed;
>  
>  struct drm_device;
> +struct drm_connector;
>  
>  bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
> +int drm_connector_attach_content_protection_property(
> +		struct drm_connector *connector, bool hdcp_content_type);
>  #endif
> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
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] 33+ messages in thread

* Re: [PATCH v5 08/12] drm: uevent for connector status change
  2019-04-18  8:58 ` [PATCH v5 08/12] drm: uevent for connector status change Ramalingam C
@ 2019-04-29  7:33   ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-29  7:33 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Thu, Apr 18, 2019 at 02:28:01PM +0530, Ramalingam C wrote:
> DRM API for generating uevent for a status changes of connector's
> property.
> 
> This uevent will have following details related to the status change:
> 
>   HOTPLUG=1, CONNECTOR=<connector_id> and PROPERTY=<property_id>
> v2:
>   Minor fixes at KDoc comments [Daniel]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/drm_sysfs.c | 31 +++++++++++++++++++++++++++++++
>  include/drm/drm_sysfs.h     |  5 ++++-
>  2 files changed, 35 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/drm_sysfs.c b/drivers/gpu/drm/drm_sysfs.c
> index 18b1ac442997..e8f1fd73677f 100644
> --- a/drivers/gpu/drm/drm_sysfs.c
> +++ b/drivers/gpu/drm/drm_sysfs.c
> @@ -320,6 +320,9 @@ void drm_sysfs_lease_event(struct drm_device *dev)
>   * Send a uevent for the DRM device specified by @dev.  Currently we only
>   * set HOTPLUG=1 in the uevent environment, but this could be expanded to
>   * deal with other types of events.
> + *
> + * Any new uapi should be using the drm_sysfs_connector_status_event()
> + * for uevents on connector status change.
>   */
>  void drm_sysfs_hotplug_event(struct drm_device *dev)
>  {
> @@ -332,6 +335,34 @@ void drm_sysfs_hotplug_event(struct drm_device *dev)
>  }
>  EXPORT_SYMBOL(drm_sysfs_hotplug_event);
>  
> +/**
> + * drm_sysfs_connector_status_event - generate a DRM uevent for connector
> + * property status change
> + * @connector: connector on which property status changed
> + * @property: connector property whoes status changed.
> + *
> + * Send a uevent for the DRM device specified by @dev.  Currently we
> + * set HOTPLUG=1 and connector id along with the attached property id
> + * related to the status change.
> + */
> +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> +				      struct drm_property *property)
> +{
> +	struct drm_device *dev = connector->dev;
> +	char hotplug_str[] = "HOTPLUG=1", conn_id[30], prop_id[30];
> +	char *envp[4] = { hotplug_str, conn_id, prop_id, NULL };
> +
> +	snprintf(conn_id, ARRAY_SIZE(conn_id),
> +		 "CONNECTOR=%u", connector->base.id);
> +	snprintf(prop_id, ARRAY_SIZE(prop_id),
> +		 "PROPERTY=%u", property->base.id);

Maybe double-check that property is attached to connector, and WARN if
not? Just to catch mistakes in driver programming.

With that: Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>


> +
> +	DRM_DEBUG("generating connector status event\n");
> +
> +	kobject_uevent_env(&dev->primary->kdev->kobj, KOBJ_CHANGE, envp);
> +}
> +EXPORT_SYMBOL(drm_sysfs_connector_status_event);
> +
>  static void drm_sysfs_release(struct device *dev)
>  {
>  	kfree(dev);
> diff --git a/include/drm/drm_sysfs.h b/include/drm/drm_sysfs.h
> index 4f311e836cdc..d454ef617b2c 100644
> --- a/include/drm/drm_sysfs.h
> +++ b/include/drm/drm_sysfs.h
> @@ -4,10 +4,13 @@
>  
>  struct drm_device;
>  struct device;
> +struct drm_connector;
> +struct drm_property;
>  
>  int drm_class_device_register(struct device *dev);
>  void drm_class_device_unregister(struct device *dev);
>  
>  void drm_sysfs_hotplug_event(struct drm_device *dev);
> -
> +void drm_sysfs_connector_status_event(struct drm_connector *connector,
> +				      struct drm_property *property);
>  #endif
> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
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] 33+ messages in thread

* Re: [PATCH v5 09/12] drm/hdcp: update content protection property with uevent
  2019-04-18  8:58 ` [PATCH v5 09/12] drm/hdcp: update content protection property with uevent Ramalingam C
@ 2019-04-29  7:35   ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-29  7:35 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel, gwan-gyeong.mun

On Thu, Apr 18, 2019 at 02:28:02PM +0530, Ramalingam C wrote:
> drm function is defined and exported to update a connector's
> content protection property state and to generate a uevent along
> with it.
> 
> v2:
>   Update only when state is different from old one.
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/drm_hdcp.c | 16 ++++++++++++++++
>  include/drm/drm_hdcp.h     |  2 ++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> index a0960507e4ff..5640c4e744fe 100644
> --- a/drivers/gpu/drm/drm_hdcp.c
> +++ b/drivers/gpu/drm/drm_hdcp.c
> @@ -415,3 +415,19 @@ int drm_connector_attach_content_protection_property(
>  	return 0;
>  }
>  EXPORT_SYMBOL(drm_connector_attach_content_protection_property);
> +

Needs kerneldoc. Plus I think a note in the attach function that sets up
hdcp for a connector that it should be used.

Plus we need an ack from userspace people (weston?) that they're using
this new uapi and are happy with it.

> +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> +					u64 val)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct drm_connector_state *state = connector->state;
> +
> +	WARN_ON(!drm_modeset_is_locked(&dev->mode_config.connection_mutex));
> +	if (state->content_protection == val)
> +		return;
> +
> +	state->content_protection = val;
> +	drm_sysfs_connector_status_event(connector,
> +				 dev->mode_config.content_protection_property);
> +}
> +EXPORT_SYMBOL(drm_hdcp_update_content_protection);

With all that addressed has my Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index 145c81ba1e09..9457c7ec0d37 100644
> --- a/include/drm/drm_hdcp.h
> +++ b/include/drm/drm_hdcp.h
> @@ -304,4 +304,6 @@ struct drm_connector;
>  bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
>  int drm_connector_attach_content_protection_property(
>  		struct drm_connector *connector, bool hdcp_content_type);
> +void drm_hdcp_update_content_protection(struct drm_connector *connector,
> +					u64 val);
>  #endif
> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

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

* Re: [PATCH v5 10/12] drm/i915: update the hdcp state with uevent
  2019-04-18  8:58 ` [PATCH v5 10/12] drm/i915: update the hdcp state " Ramalingam C
@ 2019-04-29  7:35   ` Daniel Vetter
  0 siblings, 0 replies; 33+ messages in thread
From: Daniel Vetter @ 2019-04-29  7:35 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Thu, Apr 18, 2019 at 02:28:03PM +0530, Ramalingam C wrote:
> drm function to update the content protection property state and to
> generate a uevent is invoked from the intel hdcp property work.
> 
> Hence whenever kernel changes the property state, userspace will be
> updated with a uevent.
> 
> v2:
>   state update is moved into drm function [daniel]
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>

Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>

> ---
>  drivers/gpu/drm/i915/intel_hdcp.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c
> index de634f3fbd1b..84ac23ea75af 100644
> --- a/drivers/gpu/drm/i915/intel_hdcp.c
> +++ b/drivers/gpu/drm/i915/intel_hdcp.c
> @@ -866,7 +866,6 @@ static void intel_hdcp_prop_work(struct work_struct *work)
>  					       prop_work);
>  	struct intel_connector *connector = intel_hdcp_to_connector(hdcp);
>  	struct drm_device *dev = connector->base.dev;
> -	struct drm_connector_state *state;
>  
>  	drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
>  	mutex_lock(&hdcp->mutex);
> @@ -876,10 +875,9 @@ static void intel_hdcp_prop_work(struct work_struct *work)
>  	 * those to UNDESIRED is handled by core. If value == UNDESIRED,
>  	 * we're running just after hdcp has been disabled, so just exit
>  	 */
> -	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED) {
> -		state = connector->base.state;
> -		state->content_protection = hdcp->value;
> -	}
> +	if (hdcp->value != DRM_MODE_CONTENT_PROTECTION_UNDESIRED)
> +		drm_hdcp_update_content_protection(&connector->base,
> +						   hdcp->value);
>  
>  	mutex_unlock(&hdcp->mutex);
>  	drm_modeset_unlock(&dev->mode_config.connection_mutex);
> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
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] 33+ messages in thread

* Re: [PATCH v5 11/12] drm: Add CP downstream_info property
  2019-04-18  8:58 ` [PATCH v5 11/12] drm: Add CP downstream_info property Ramalingam C
@ 2019-04-29  7:38   ` Daniel Vetter
  2019-04-29 14:46     ` Ramalingam C
  0 siblings, 1 reply; 33+ messages in thread
From: Daniel Vetter @ 2019-04-29  7:38 UTC (permalink / raw)
  To: Ramalingam C; +Cc: intel-gfx, dri-devel

On Thu, Apr 18, 2019 at 02:28:04PM +0530, Ramalingam C wrote:
> This patch adds a optional CP downstream info blob property to the
> connectors. This enables the Userspace to read the information of HDCP
> authenticated downstream topology.
> 
> Driver will update this blob with all downstream information at the
> end of the authentication.
> 
> In case userspace configures this platform as repeater, then this
> information is needed for the authentication with upstream HDCP
> transmitter.
> 
> v2:
>   s/cp_downstream/content_protection_downstream [daniel]
> v3:
>   s/content_protection_downstream/hdcp_topology [daniel]
> v4:
>   hdcp_topology_info struct is added with explicit padding [Daniel]
> v5:
>   Rebased.
> 
> Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> ---
>  drivers/gpu/drm/drm_atomic_uapi.c |  3 ++
>  drivers/gpu/drm/drm_connector.c   | 20 ++++++++++
>  drivers/gpu/drm/drm_hdcp.c        | 65 +++++++++++++++++++++++++++++++
>  include/drm/drm_connector.h       |  6 +++
>  include/drm/drm_hdcp.h            |  6 +++
>  include/drm/drm_mode_config.h     |  6 +++
>  include/uapi/drm/drm_mode.h       | 37 ++++++++++++++++++
>  7 files changed, 143 insertions(+)
> 
> diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> index 0b0747869963..1c9e1ab0d536 100644
> --- a/drivers/gpu/drm/drm_atomic_uapi.c
> +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> @@ -813,6 +813,9 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
>  		*val = state->content_protection;
>  	} else if (property == config->hdcp_content_type_property) {
>  		*val = state->hdcp_content_type;
> +	} else if (property == config->hdcp_topology_property) {
> +		*val = connector->hdcp_topology_blob_ptr ?
> +			connector->hdcp_topology_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 436cf8e764cc..033ced774d37 100644
> --- a/drivers/gpu/drm/drm_connector.c
> +++ b/drivers/gpu/drm/drm_connector.c
> @@ -246,6 +246,7 @@ int drm_connector_init(struct drm_device *dev,
>  	mutex_init(&connector->mutex);
>  	connector->edid_blob_ptr = NULL;
>  	connector->tile_blob_ptr = NULL;
> +	connector->hdcp_topology_blob_ptr = NULL;
>  	connector->status = connector_status_unknown;
>  	connector->display_info.panel_orientation =
>  		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
> @@ -972,6 +973,25 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
>   *	authentication process. If content type is changed when
>   *	content_protection is not UNDESIRED, then kernel will disable the HDCP
>   *	and re-enable with new type in the same atomic commit
> + * HDCP Topology:
> + *	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)    |
> + * |                               |                              |
> + * |                                                              |
> + * +--------------------------------------------------------------+

Hm I think this misrenders, since the table isn't indented or marked as
fixed with. Did you check the output of $make htmldocs?

> + *
> + *	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
> diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> index 5640c4e744fe..c0d3fc93fc50 100644
> --- a/drivers/gpu/drm/drm_hdcp.c
> +++ b/drivers/gpu/drm/drm_hdcp.c
> @@ -431,3 +431,68 @@ void drm_hdcp_update_content_protection(struct drm_connector *connector,
>  				 dev->mode_config.content_protection_property);
>  }
>  EXPORT_SYMBOL(drm_hdcp_update_content_protection);
> +
> +/**
> + * drm_connector_attach_hdcp_topology_property - attach hdcp topology property
> + *
> + * @connector: connector to attach hdcp topology property with.
> + *
> + * This is used to add support for hdcp topology support 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 blob_id of the hdcp topology info will be set to
> + * &drm_connector_state.hdcp_topology
> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int drm_connector_attach_hdcp_topology_property(struct drm_connector *connector)
> +{
> +	struct drm_device *dev = connector->dev;
> +	struct drm_property *prop = dev->mode_config.hdcp_topology_property;
> +
> +	if (!prop)
> +		prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
> +					   DRM_MODE_PROP_IMMUTABLE,
> +					   "HDCP Topology", 0);
> +	if (!prop)
> +		return -ENOMEM;
> +
> +	drm_object_attach_property(&connector->base, prop, 0);
> +	dev->mode_config.hdcp_topology_property = prop;
> +	return 0;
> +}
> +EXPORT_SYMBOL(drm_connector_attach_hdcp_topology_property);
> +
> +/**
> + * drm_connector_update_hdcp_topology_property - update the hdcp topology
> + * property of a connector
> + * @connector: drm connector, the topology is associated to
> + * @hdcp_topology_info: new content for the blob of hdcp_topology_property
> + *
> + * This function creates a new blob modeset object and assigns its id to the
> + * connector's hdcp_topology_property.
> + *
> + * Returns:
> + * Zero on success, negative errno on failure.
> + */
> +int
> +drm_connector_update_hdcp_topology_property(struct drm_connector *connector,
> +					const struct hdcp_topology_info *info)
> +{
> +	struct drm_device *dev = connector->dev;
> +	int ret;
> +
> +	if (!info)
> +		return -EINVAL;
> +
> +	ret = drm_property_replace_global_blob(dev,
> +			&connector->hdcp_topology_blob_ptr,
> +			sizeof(struct hdcp_topology_info),
> +			info, &connector->base,
> +			dev->mode_config.hdcp_topology_property);
> +	return ret;
> +}

Hm, I'd put this into the previous function that also sends out the
uevent. That way we can guarantee that we update everyting _before_ we
send out the uevent to signal to userspace that it should take some
action.

> +EXPORT_SYMBOL(drm_connector_update_hdcp_topology_property);
> diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> index 9e2f1a9de2a0..180f8f4d4526 100644
> --- a/include/drm/drm_connector.h
> +++ b/include/drm/drm_connector.h
> @@ -1050,6 +1050,12 @@ struct drm_connector {
>  	/** @properties: property tracking for this connector */
>  	struct drm_object_properties properties;
>  
> +	/**
> +	 * @hdcp_topology_blob_ptr: DRM BLOB pointer for hdcp downstream
> +	 * topology information.
> +	 */
> +	struct drm_property_blob *hdcp_topology_blob_ptr;
> +
>  	/**
>  	 * @scaling_mode_property: Optional atomic property to control the
>  	 * upscaling. See drm_connector_attach_content_protection_property().
> diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> index 9457c7ec0d37..011f35e121a5 100644
> --- a/include/drm/drm_hdcp.h
> +++ b/include/drm/drm_hdcp.h
> @@ -300,10 +300,16 @@ struct hdcp2_srm_header {
>  
>  struct drm_device;
>  struct drm_connector;
> +struct hdcp_topology_info;
>  
>  bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
>  int drm_connector_attach_content_protection_property(
>  		struct drm_connector *connector, bool hdcp_content_type);
>  void drm_hdcp_update_content_protection(struct drm_connector *connector,
>  					u64 val);
> +int drm_connector_attach_hdcp_topology_property(
> +				struct drm_connector *connector);
> +int drm_connector_update_hdcp_topology_property(
> +				struct drm_connector *connector,
> +				const struct hdcp_topology_info *info);
>  #endif
> diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> index b359b5b71eb9..4349b614fa15 100644
> --- a/include/drm/drm_mode_config.h
> +++ b/include/drm/drm_mode_config.h
> @@ -848,6 +848,12 @@ struct drm_mode_config {
>  	 */
>  	struct drm_property *hdcp_content_type_property;
>  
> +	/**
> +	 * @hdcp_topology_property: DRM BLOB property for hdcp downstream
> +	 * topology information.
> +	 */
> +	struct drm_property *hdcp_topology_property;
> +
>  	/* dumb ioctl parameters */
>  	uint32_t preferred_depth, prefer_shadow;
>  
> diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> index 8ac03351fdee..9d7cdfab4962 100644
> --- a/include/uapi/drm/drm_mode.h
> +++ b/include/uapi/drm/drm_mode.h
> @@ -213,6 +213,43 @@ extern "C" {
>  #define DRM_MODE_HDCP_CONTENT_TYPE0		0
>  #define DRM_MODE_HDCP_CONTENT_TYPE1		1
>  
> +#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 hdcp_topology_info {
> +	/* Version of HDCP authenticated (1.4/2.2) */
> +	__u32 ver_in_force;
> +
> +	/* Applicable only for HDCP2.2 */
> +	__u32 content_type;
> +
> +	/* KSV of immediate HDCP Sink. In Little-Endian Format. */
> +	__u8 bksv[DRM_MODE_HDCP_KSV_LEN];
> +
> +	/* Whether Immediate HDCP sink is a repeater? */
> +	__u8 is_repeater;
> +
> +	/* Depth received from immediate downstream repeater */
> +	__u8 depth;
> +	__u8 pad1;
> +
> +	/* 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.
> +	 */
> +	__u8 ksv_list[DRM_MODE_HDCP_KSV_LEN * DRM_MODE_HDCP_MAX_DEVICE_CNT];
> +	__u8 pad2[5];
> +} __packed;

So I think we need userspace for this, but not sure where the discussions
on that are right now. Is this feasible, or this and follow-up i915 patch
more fyi and not for upstream?
-Daniel

> +
>  struct drm_mode_modeinfo {
>  	__u32 clock;
>  	__u16 hdisplay;
> -- 
> 2.19.1
> 

-- 
Daniel Vetter
Software Engineer, Intel Corporation
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] 33+ messages in thread

* Re: [PATCH v5 11/12] drm: Add CP downstream_info property
  2019-04-29  7:38   ` Daniel Vetter
@ 2019-04-29 14:46     ` Ramalingam C
  0 siblings, 0 replies; 33+ messages in thread
From: Ramalingam C @ 2019-04-29 14:46 UTC (permalink / raw)
  To: Daniel Vetter; +Cc: intel-gfx, dri-devel

On 2019-04-29 at 09:38:32 +0200, Daniel Vetter wrote:
> On Thu, Apr 18, 2019 at 02:28:04PM +0530, Ramalingam C wrote:
> > This patch adds a optional CP downstream info blob property to the
> > connectors. This enables the Userspace to read the information of HDCP
> > authenticated downstream topology.
> > 
> > Driver will update this blob with all downstream information at the
> > end of the authentication.
> > 
> > In case userspace configures this platform as repeater, then this
> > information is needed for the authentication with upstream HDCP
> > transmitter.
> > 
> > v2:
> >   s/cp_downstream/content_protection_downstream [daniel]
> > v3:
> >   s/content_protection_downstream/hdcp_topology [daniel]
> > v4:
> >   hdcp_topology_info struct is added with explicit padding [Daniel]
> > v5:
> >   Rebased.
> > 
> > Signed-off-by: Ramalingam C <ramalingam.c@intel.com>
> > ---
> >  drivers/gpu/drm/drm_atomic_uapi.c |  3 ++
> >  drivers/gpu/drm/drm_connector.c   | 20 ++++++++++
> >  drivers/gpu/drm/drm_hdcp.c        | 65 +++++++++++++++++++++++++++++++
> >  include/drm/drm_connector.h       |  6 +++
> >  include/drm/drm_hdcp.h            |  6 +++
> >  include/drm/drm_mode_config.h     |  6 +++
> >  include/uapi/drm/drm_mode.h       | 37 ++++++++++++++++++
> >  7 files changed, 143 insertions(+)
> > 
> > diff --git a/drivers/gpu/drm/drm_atomic_uapi.c b/drivers/gpu/drm/drm_atomic_uapi.c
> > index 0b0747869963..1c9e1ab0d536 100644
> > --- a/drivers/gpu/drm/drm_atomic_uapi.c
> > +++ b/drivers/gpu/drm/drm_atomic_uapi.c
> > @@ -813,6 +813,9 @@ drm_atomic_connector_get_property(struct drm_connector *connector,
> >  		*val = state->content_protection;
> >  	} else if (property == config->hdcp_content_type_property) {
> >  		*val = state->hdcp_content_type;
> > +	} else if (property == config->hdcp_topology_property) {
> > +		*val = connector->hdcp_topology_blob_ptr ?
> > +			connector->hdcp_topology_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 436cf8e764cc..033ced774d37 100644
> > --- a/drivers/gpu/drm/drm_connector.c
> > +++ b/drivers/gpu/drm/drm_connector.c
> > @@ -246,6 +246,7 @@ int drm_connector_init(struct drm_device *dev,
> >  	mutex_init(&connector->mutex);
> >  	connector->edid_blob_ptr = NULL;
> >  	connector->tile_blob_ptr = NULL;
> > +	connector->hdcp_topology_blob_ptr = NULL;
> >  	connector->status = connector_status_unknown;
> >  	connector->display_info.panel_orientation =
> >  		DRM_MODE_PANEL_ORIENTATION_UNKNOWN;
> > @@ -972,6 +973,25 @@ static const struct drm_prop_enum_list hdmi_colorspaces[] = {
> >   *	authentication process. If content type is changed when
> >   *	content_protection is not UNDESIRED, then kernel will disable the HDCP
> >   *	and re-enable with new type in the same atomic commit
> > + * HDCP Topology:
> > + *	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)    |
> > + * |                               |                              |
> > + * |                                                              |
> > + * +--------------------------------------------------------------+
> 
> Hm I think this misrenders, since the table isn't indented or marked as
> fixed with. Did you check the output of $make htmldocs?
Yes checked on doc output. corrupted. I will fix it.

> 
> > + *
> > + *	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
> > diff --git a/drivers/gpu/drm/drm_hdcp.c b/drivers/gpu/drm/drm_hdcp.c
> > index 5640c4e744fe..c0d3fc93fc50 100644
> > --- a/drivers/gpu/drm/drm_hdcp.c
> > +++ b/drivers/gpu/drm/drm_hdcp.c
> > @@ -431,3 +431,68 @@ void drm_hdcp_update_content_protection(struct drm_connector *connector,
> >  				 dev->mode_config.content_protection_property);
> >  }
> >  EXPORT_SYMBOL(drm_hdcp_update_content_protection);
> > +
> > +/**
> > + * drm_connector_attach_hdcp_topology_property - attach hdcp topology property
> > + *
> > + * @connector: connector to attach hdcp topology property with.
> > + *
> > + * This is used to add support for hdcp topology support 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 blob_id of the hdcp topology info will be set to
> > + * &drm_connector_state.hdcp_topology
> > + *
> > + * Returns:
> > + * Zero on success, negative errno on failure.
> > + */
> > +int drm_connector_attach_hdcp_topology_property(struct drm_connector *connector)
> > +{
> > +	struct drm_device *dev = connector->dev;
> > +	struct drm_property *prop = dev->mode_config.hdcp_topology_property;
> > +
> > +	if (!prop)
> > +		prop = drm_property_create(dev, DRM_MODE_PROP_BLOB |
> > +					   DRM_MODE_PROP_IMMUTABLE,
> > +					   "HDCP Topology", 0);
> > +	if (!prop)
> > +		return -ENOMEM;
> > +
> > +	drm_object_attach_property(&connector->base, prop, 0);
> > +	dev->mode_config.hdcp_topology_property = prop;
> > +	return 0;
> > +}
> > +EXPORT_SYMBOL(drm_connector_attach_hdcp_topology_property);
> > +
> > +/**
> > + * drm_connector_update_hdcp_topology_property - update the hdcp topology
> > + * property of a connector
> > + * @connector: drm connector, the topology is associated to
> > + * @hdcp_topology_info: new content for the blob of hdcp_topology_property
> > + *
> > + * This function creates a new blob modeset object and assigns its id to the
> > + * connector's hdcp_topology_property.
> > + *
> > + * Returns:
> > + * Zero on success, negative errno on failure.
> > + */
> > +int
> > +drm_connector_update_hdcp_topology_property(struct drm_connector *connector,
> > +					const struct hdcp_topology_info *info)
> > +{
> > +	struct drm_device *dev = connector->dev;
> > +	int ret;
> > +
> > +	if (!info)
> > +		return -EINVAL;
> > +
> > +	ret = drm_property_replace_global_blob(dev,
> > +			&connector->hdcp_topology_blob_ptr,
> > +			sizeof(struct hdcp_topology_info),
> > +			info, &connector->base,
> > +			dev->mode_config.hdcp_topology_property);
> > +	return ret;
> > +}
> 
> Hm, I'd put this into the previous function that also sends out the
> uevent. That way we can guarantee that we update everyting _before_ we
> send out the uevent to signal to userspace that it should take some
> action.

That will not work as above fucntion wont be called for the disable
request. Where as this blob needs to be removed on disable. So I prefer
to keep this as separate.
> 
> > +EXPORT_SYMBOL(drm_connector_update_hdcp_topology_property);
> > diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
> > index 9e2f1a9de2a0..180f8f4d4526 100644
> > --- a/include/drm/drm_connector.h
> > +++ b/include/drm/drm_connector.h
> > @@ -1050,6 +1050,12 @@ struct drm_connector {
> >  	/** @properties: property tracking for this connector */
> >  	struct drm_object_properties properties;
> >  
> > +	/**
> > +	 * @hdcp_topology_blob_ptr: DRM BLOB pointer for hdcp downstream
> > +	 * topology information.
> > +	 */
> > +	struct drm_property_blob *hdcp_topology_blob_ptr;
> > +
> >  	/**
> >  	 * @scaling_mode_property: Optional atomic property to control the
> >  	 * upscaling. See drm_connector_attach_content_protection_property().
> > diff --git a/include/drm/drm_hdcp.h b/include/drm/drm_hdcp.h
> > index 9457c7ec0d37..011f35e121a5 100644
> > --- a/include/drm/drm_hdcp.h
> > +++ b/include/drm/drm_hdcp.h
> > @@ -300,10 +300,16 @@ struct hdcp2_srm_header {
> >  
> >  struct drm_device;
> >  struct drm_connector;
> > +struct hdcp_topology_info;
> >  
> >  bool drm_hdcp_ksvs_revocated(struct drm_device *dev, u8 *ksvs, u32 ksv_count);
> >  int drm_connector_attach_content_protection_property(
> >  		struct drm_connector *connector, bool hdcp_content_type);
> >  void drm_hdcp_update_content_protection(struct drm_connector *connector,
> >  					u64 val);
> > +int drm_connector_attach_hdcp_topology_property(
> > +				struct drm_connector *connector);
> > +int drm_connector_update_hdcp_topology_property(
> > +				struct drm_connector *connector,
> > +				const struct hdcp_topology_info *info);
> >  #endif
> > diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
> > index b359b5b71eb9..4349b614fa15 100644
> > --- a/include/drm/drm_mode_config.h
> > +++ b/include/drm/drm_mode_config.h
> > @@ -848,6 +848,12 @@ struct drm_mode_config {
> >  	 */
> >  	struct drm_property *hdcp_content_type_property;
> >  
> > +	/**
> > +	 * @hdcp_topology_property: DRM BLOB property for hdcp downstream
> > +	 * topology information.
> > +	 */
> > +	struct drm_property *hdcp_topology_property;
> > +
> >  	/* dumb ioctl parameters */
> >  	uint32_t preferred_depth, prefer_shadow;
> >  
> > diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
> > index 8ac03351fdee..9d7cdfab4962 100644
> > --- a/include/uapi/drm/drm_mode.h
> > +++ b/include/uapi/drm/drm_mode.h
> > @@ -213,6 +213,43 @@ extern "C" {
> >  #define DRM_MODE_HDCP_CONTENT_TYPE0		0
> >  #define DRM_MODE_HDCP_CONTENT_TYPE1		1
> >  
> > +#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 hdcp_topology_info {
> > +	/* Version of HDCP authenticated (1.4/2.2) */
> > +	__u32 ver_in_force;
> > +
> > +	/* Applicable only for HDCP2.2 */
> > +	__u32 content_type;
> > +
> > +	/* KSV of immediate HDCP Sink. In Little-Endian Format. */
> > +	__u8 bksv[DRM_MODE_HDCP_KSV_LEN];
> > +
> > +	/* Whether Immediate HDCP sink is a repeater? */
> > +	__u8 is_repeater;
> > +
> > +	/* Depth received from immediate downstream repeater */
> > +	__u8 depth;
> > +	__u8 pad1;
> > +
> > +	/* 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.
> > +	 */
> > +	__u8 ksv_list[DRM_MODE_HDCP_KSV_LEN * DRM_MODE_HDCP_MAX_DEVICE_CNT];
> > +	__u8 pad2[5];
> > +} __packed;
> 
> So I think we need userspace for this, but not sure where the discussions
> on that are right now. Is this feasible, or this and follow-up i915 patch
> more fyi and not for upstream?

This is not for upstream, as i couldn't comeup with userspace. I will
mention that in the commit msg. Otherwise share your view on the patch.

-Ram

> -Daniel
> 
> > +
> >  struct drm_mode_modeinfo {
> >  	__u32 clock;
> >  	__u16 hdisplay;
> > -- 
> > 2.19.1
> > 
> 
> -- 
> Daniel Vetter
> Software Engineer, Intel Corporation
> 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] 33+ messages in thread

end of thread, other threads:[~2019-04-29 14:46 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-18  8:57 [PATCH v5 00/12] HDCP2.2 Phase II Ramalingam C
2019-04-18  8:57 ` [PATCH v5 01/12] drm: move content protection property to mode_config Ramalingam C
2019-04-23  7:38   ` Daniel Vetter
2019-04-18  8:57 ` [PATCH v5 02/12] drm/i915: debugfs: HDCP2.2 capability read Ramalingam C
2019-04-18  8:57 ` [PATCH v5 03/12] drm: Add Content protection type property Ramalingam C
2019-04-23  7:44   ` Daniel Vetter
2019-04-18  8:57 ` [PATCH v5 04/12] drm/i915: Attach content " Ramalingam C
2019-04-23  8:11   ` Daniel Vetter
2019-04-23 11:17     ` Ramalingam C
2019-04-23 12:10       ` Daniel Vetter
2019-04-18  8:57 ` [PATCH v5 05/12] drm: revocation check at drm subsystem Ramalingam C
2019-04-29  7:26   ` Daniel Vetter
2019-04-29  7:30     ` Daniel Vetter
2019-04-18  8:57 ` [PATCH v5 06/12] drm/i915: SRM revocation check for HDCP1.4 and 2.2 Ramalingam C
2019-04-29  7:28   ` Daniel Vetter
2019-04-18  8:58 ` [PATCH v5 07/12] drm/hdcp: gathering hdcp related code into drm_hdcp.c Ramalingam C
2019-04-29  7:31   ` Daniel Vetter
2019-04-18  8:58 ` [PATCH v5 08/12] drm: uevent for connector status change Ramalingam C
2019-04-29  7:33   ` Daniel Vetter
2019-04-18  8:58 ` [PATCH v5 09/12] drm/hdcp: update content protection property with uevent Ramalingam C
2019-04-29  7:35   ` Daniel Vetter
2019-04-18  8:58 ` [PATCH v5 10/12] drm/i915: update the hdcp state " Ramalingam C
2019-04-29  7:35   ` Daniel Vetter
2019-04-18  8:58 ` [PATCH v5 11/12] drm: Add CP downstream_info property Ramalingam C
2019-04-29  7:38   ` Daniel Vetter
2019-04-29 14:46     ` Ramalingam C
2019-04-18  8:58 ` [PATCH v5 12/12] drm/i915: Populate downstream info for HDCP Ramalingam C
2019-04-18 10:35 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev6) Patchwork
2019-04-18 10:43 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-04-18 11:17 ` ✗ Fi.CI.CHECKPATCH: warning for HDCP2.2 Phase II (rev7) Patchwork
2019-04-18 11:25 ` ✗ Fi.CI.SPARSE: " Patchwork
2019-04-18 11:45 ` ✓ Fi.CI.BAT: success " Patchwork
2019-04-18 13:51 ` ✓ Fi.CI.IGT: " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.