[igt-dev] [PATCH i-g-t v6 3/8] kms_content_protection: Content type support

Ramalingam C ramalingam.c at intel.com
Thu May 2 13:16:20 UTC 2019


Adds a connector property called "CP_Content_Type"

Content Type takes two values which classifies the content stream:
	Type 0: Stream that can be tranmitted on HDCP1.4/HDCP2.2
	Type 1: Stream that needs HDCP2.2 encryption only.

So when Type 1 is set KMD is forced to enable HDCP2.2 only.

For Type 0 request, Kernel chooses the highest capable HDCP version
(v2.2) first. If that fails, then it fall back to the next availble
version(v1.4) before abondoning HDCP autehntication attempts.

Please note content_type is allowed to be updated when "Content
Protection" is in UNDESIRED state.

v2:
  s/cp_content_type/content_ptotection_type [danvet]
v3:
  s/content_protection_type/HDCP Content Type [Pekka]
v4:
  Rebased

Signed-off-by: Ramalingam C <ramalingam.c at intel.com>
Acked-by: Daniel Vetter <daniel.vetter at ffwll.ch>
---
 lib/igt_kms.c                  |  1 +
 lib/igt_kms.h                  |  1 +
 tests/kms_content_protection.c | 74 +++++++++++++++++++++++++++-------
 3 files changed, 62 insertions(+), 14 deletions(-)

diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index df9aafd24bf8..18f0556687de 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -222,6 +222,7 @@ const char * const igt_connector_prop_names[IGT_NUM_CONNECTOR_PROPS] = {
 	[IGT_CONNECTOR_BROADCAST_RGB] = "Broadcast RGB",
 	[IGT_CONNECTOR_CONTENT_PROTECTION] = "Content Protection",
 	[IGT_CONNECTOR_VRR_CAPABLE] = "vrr_capable",
+	[IGT_CONNECTOR_HDCP_CONTENT_TYPE] = "HDCP Content Type",
 };
 
 /*
diff --git a/lib/igt_kms.h b/lib/igt_kms.h
index 38bdc08f3d50..b1430a517305 100644
--- a/lib/igt_kms.h
+++ b/lib/igt_kms.h
@@ -123,6 +123,7 @@ enum igt_atomic_connector_properties {
        IGT_CONNECTOR_BROADCAST_RGB,
        IGT_CONNECTOR_CONTENT_PROTECTION,
        IGT_CONNECTOR_VRR_CAPABLE,
+       IGT_CONNECTOR_HDCP_CONTENT_TYPE,
        IGT_NUM_CONNECTOR_PROPS
 };
 
diff --git a/tests/kms_content_protection.c b/tests/kms_content_protection.c
index e3bb39f42ada..488c508b0bb0 100644
--- a/tests/kms_content_protection.c
+++ b/tests/kms_content_protection.c
@@ -44,6 +44,13 @@ struct data {
 #define CP_DESIRED				1
 #define CP_ENABLED				2
 
+/*
+ * HDCP_CONTENT_TYPE_0 can be handled on both HDCP1.4 and HDCP2.2. Where as
+ * HDCP_CONTENT_TYPE_1 can be handled only through HDCP2.2.
+ */
+#define HDCP_CONTENT_TYPE_0				0
+#define HDCP_CONTENT_TYPE_1				1
+
 #define LIC_PERIOD_MSEC				(4 * 1000)
 /* Kernel retry count=3, Max time per authentication allowed = 6Sec */
 #define KERNEL_AUTH_TIME_ALLOWED_MSEC		(3 *  6 * 1000)
@@ -159,7 +166,8 @@ static void modeset_with_fb(const enum pipe pipe, igt_output_t *output,
 	commit_display_and_wait_for_flip(s);
 }
 
-static bool test_cp_enable(igt_output_t *output, enum igt_commit_style s)
+static bool test_cp_enable(igt_output_t *output, enum igt_commit_style s,
+			   int content_type)
 {
 	igt_display_t *display = &data.display;
 	igt_plane_t *primary;
@@ -169,6 +177,10 @@ static bool test_cp_enable(igt_output_t *output, enum igt_commit_style s)
 
 	igt_output_set_prop_value(output,
 				  IGT_CONNECTOR_CONTENT_PROTECTION, CP_DESIRED);
+	if (output->props[IGT_CONNECTOR_HDCP_CONTENT_TYPE])
+		igt_output_set_prop_value(output,
+					  IGT_CONNECTOR_HDCP_CONTENT_TYPE,
+					  content_type);
 	igt_display_commit2(display, s);
 
 	ret = wait_for_prop_value(output, CP_ENABLED,
@@ -205,13 +217,14 @@ static void test_cp_disable(igt_output_t *output, enum igt_commit_style s)
 }
 
 static void test_cp_enable_with_retry(igt_output_t *output,
-				      enum igt_commit_style s, int retry)
+				      enum igt_commit_style s, int retry,
+				      int content_type)
 {
 	bool ret;
 
 	do {
 		test_cp_disable(output, s);
-		ret = test_cp_enable(output, s);
+		ret = test_cp_enable(output, s, content_type);
 
 		if (!ret && --retry)
 			igt_debug("Retry (%d/2) ...\n", 3 - retry);
@@ -244,7 +257,8 @@ static void test_cp_lic(igt_output_t *output)
 }
 
 static void test_content_protection_on_output(igt_output_t *output,
-					      enum igt_commit_style s)
+					      enum igt_commit_style s,
+					      int content_type)
 {
 	igt_display_t *display = &data.display;
 	igt_plane_t *primary;
@@ -265,7 +279,7 @@ static void test_content_protection_on_output(igt_output_t *output,
 			continue;
 
 		modeset_with_fb(pipe, output, s);
-		test_cp_enable_with_retry(output, s, 3);
+		test_cp_enable_with_retry(output, s, 3, content_type);
 
 		if (data.cp_tests & CP_LIC)
 			test_cp_lic(output);
@@ -282,7 +296,8 @@ static void test_content_protection_on_output(igt_output_t *output,
 			ret = wait_for_prop_value(output, CP_ENABLED,
 						  KERNEL_AUTH_TIME_ALLOWED_MSEC);
 			if (!ret)
-				test_cp_enable_with_retry(output, s, 2);
+				test_cp_enable_with_retry(output, s,
+							  2, content_type);
 		}
 
 		test_cp_disable(output, s);
@@ -309,7 +324,8 @@ static void __debugfs_read(int fd, const char *param, char *buf, int len)
 
 #define debugfs_read(fd, p, arr) __debugfs_read(fd, p, arr, sizeof(arr))
 
-#define MAX_SINK_HDCP_CAP_BUF_LEN	500
+#define MAX_SINK_HDCP_CAP_BUF_LEN	5000
+
 static bool sink_hdcp_capable(igt_output_t *output)
 {
 	char buf[MAX_SINK_HDCP_CAP_BUF_LEN];
@@ -327,9 +343,25 @@ static bool sink_hdcp_capable(igt_output_t *output)
 	return strstr(buf, "HDCP1.4");
 }
 
+static bool sink_hdcp2_capable(igt_output_t *output)
+{
+	char buf[MAX_SINK_HDCP_CAP_BUF_LEN];
+	int fd;
+
+	fd = igt_debugfs_connector_dir(data.drm_fd, output->name, O_RDONLY);
+	if (fd < 0)
+		return false;
+
+	debugfs_read(fd, "i915_hdcp_sink_capability", buf);
+	close(fd);
+
+	igt_debug("Sink capability: %s\n", buf);
+
+	return strstr(buf, "HDCP2.2");
+}
 
 static void
-test_content_protection(enum igt_commit_style s)
+test_content_protection(enum igt_commit_style s, int content_type)
 {
 	igt_display_t *display = &data.display;
 	igt_output_t *output;
@@ -339,14 +371,23 @@ test_content_protection(enum igt_commit_style s)
 		if (!output->props[IGT_CONNECTOR_CONTENT_PROTECTION])
 			continue;
 
+		if (!output->props[IGT_CONNECTOR_HDCP_CONTENT_TYPE] &&
+		    content_type)
+			continue;
+
 		igt_info("CP Test execution on %s\n", output->name);
-		if (!sink_hdcp_capable(output)) {
+
+		if (content_type && !sink_hdcp2_capable(output)) {
+			igt_info("\tSkip %s (Sink has no HDCP2.2 support)\n",
+				 output->name);
+			continue;
+		} else if (!sink_hdcp_capable(output)) {
 			igt_info("\tSkip %s (Sink has no HDCP support)\n",
 				 output->name);
 			continue;
 		}
 
-		test_content_protection_on_output(output, s);
+		test_content_protection_on_output(output, s, content_type);
 		valid_tests++;
 	}
 
@@ -364,23 +405,28 @@ igt_main
 	}
 
 	igt_subtest("legacy")
-		test_content_protection(COMMIT_LEGACY);
+		test_content_protection(COMMIT_LEGACY, HDCP_CONTENT_TYPE_0);
 
 	igt_subtest("atomic") {
 		igt_require(data.display.is_atomic);
-		test_content_protection(COMMIT_ATOMIC);
+		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_0);
 	}
 
 	igt_subtest("atomic-dpms") {
 		igt_require(data.display.is_atomic);
 		data.cp_tests = CP_DPMS;
-		test_content_protection(COMMIT_ATOMIC);
+		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_0);
 	}
 
 	igt_subtest("LIC") {
 		igt_require(data.display.is_atomic);
 		data.cp_tests = CP_LIC;
-		test_content_protection(COMMIT_ATOMIC);
+		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_0);
+	}
+
+	igt_subtest("type1") {
+		igt_require(data.display.is_atomic);
+		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_1);
 	}
 
 	igt_fixture
-- 
2.19.1



More information about the igt-dev mailing list