[PATCH i-g-t v2 1/1] tools/intel_hdcp: Introduce intel_hdcp tool

Santhosh Reddy Guddati santhosh.reddy.guddati at intel.com
Thu Mar 20 11:28:35 UTC 2025


Add a new HDCP tool for self-testing and easy deployment
to client machines. This tool helps diagnose issues,
determining whether the problem lies in the driver or user space.

The current changes include tool skeleton and get hdcp info
on the connected outputs.

V2:
 - Update copyright to use SPDX (Jani Nikula).
 - Replace use of igt_* with fprintf and minimise usage of igt wrappers
   wherever possible (Kamil).
 - Consolidate HDCP version info and connector dump , remove redundant
   code and comments (Santhosh).

Signed-off-by: Santhosh Reddy Guddati <santhosh.reddy.guddati at intel.com>
---
 tools/intel_hdcp.c | 153 +++++++++++++++++++++++++++++++++++++++++++++
 tools/meson.build  |   1 +
 2 files changed, 154 insertions(+)
 create mode 100644 tools/intel_hdcp.c

diff --git a/tools/intel_hdcp.c b/tools/intel_hdcp.c
new file mode 100644
index 000000000..91d32ebf4
--- /dev/null
+++ b/tools/intel_hdcp.c
@@ -0,0 +1,153 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Copyright © 2025 Intel Corporation
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "igt.h"
+
+#define MAX_HDCP_BUF_LEN	5000
+typedef struct data {
+	int fd;
+	igt_display_t display;
+	struct igt_fb red, green;
+	int height, width;
+} data_t;
+
+/* TODO: Implement the actual HDCP enabling logic here
+ * Steps:
+ * 1. Open the appropriate debugfs file for the connector.
+ * 2. Enable HDCP on the output using connector properties
+ *    IGT_CONNECTOR_CONTENT_PROTECTION and IGT_CONNECTOR_HDCP_CONTENT_TYPE.
+ * 3. Check the status to ensure HDCP is enabled.
+ */
+static void enable_hdcp(void)
+{
+	fprintf(stderr, "TODO: Enable HDCP\n");
+}
+
+/* TODO: Implement the actual HDCP disabling logic here */
+static void disable_hdcp(void)
+{
+	fprintf(stderr, "TODO: Disable HDCP\n");
+}
+
+static const char *get_hdcp_version(int fd, char *connector_name)
+{
+	char buf[MAX_HDCP_BUF_LEN];
+	int ret;
+
+	ret = igt_debugfs_connector_dir(fd, connector_name, O_RDONLY);
+	if (ret < 0) {
+		fprintf(stderr, "Failed to open connector directory\n");
+		return NULL;
+	}
+
+	if (is_intel_device(fd))
+		igt_debugfs_simple_read(ret, "i915_hdcp_sink_capability", buf, sizeof(buf));
+	else
+		igt_debugfs_simple_read(ret, "hdcp_sink_capability", buf, sizeof(buf));
+
+	close(ret);
+	if (strstr(buf, "HDCP1.4") && strstr(buf, "HDCP2.2"))
+		return "HDCP1.4 and HDCP2.2";
+	else if (strstr(buf, "HDCP1.4"))
+		return "HDCP1.4";
+	else if (strstr(buf, "HDCP2.2"))
+		return "HDCP2.2";
+	else
+		return "No HDCP support";
+}
+
+static void get_hdcp_info(data_t *data)
+{
+	char *output_name;
+	drmModeRes *res = drmModeGetResources(data->fd);
+
+	if (!res) {
+		fprintf(stderr, "Failed to get DRM resources\n");
+		return;
+	}
+
+	fprintf(stderr, "Connectors:\n");
+	fprintf(stderr, "id\tencoder\tstatus\t\ttype\tHDCP\n");
+	for (int i = 0; i < res->count_connectors; i++) {
+		drmModeConnector *c;
+
+		c = drmModeGetConnectorCurrent(data->fd, res->connectors[i]);
+
+		if (!c)
+			continue;
+
+		asprintf(&output_name, "%s-%d",
+					kmstest_connector_type_str(c->connector_type),
+					c->connector_type_id);
+
+		fprintf(stderr, "%d\t%d\t%s\t%s\t%s\n",
+				 c->connector_id, c->encoder_id,
+				 kmstest_connector_status_str(c->connection),
+				 kmstest_connector_type_str(c->connector_type),
+				 get_hdcp_version(data->fd, output_name));
+
+		drmModeFreeConnector(c);
+	}
+
+	drmModeFreeResources(res);
+}
+
+static void print_usage(void)
+{
+	fprintf(stderr, "Usage: intel_hdcp [OPTIONS]\n");
+	fprintf(stderr, "Options:\n");
+	fprintf(stderr, "-i,	--info		Get HDCP Information\n");
+	fprintf(stderr, "-e,	--enable	Enable HDCP on the output\n");
+	fprintf(stderr, "-d,	--disable	Disable HDCP on the specific output\n");
+	fprintf(stderr, "-h,	--help		Display this help message\n");
+}
+
+static void test_init(data_t *data)
+{
+	data->fd = __drm_open_driver(DRIVER_ANY);
+	if (data->fd < 0) {
+		fprintf(stderr, "Failed to open DRM driver\n");
+		exit(EXIT_FAILURE);
+	}
+	igt_display_require(&data->display, data->fd);
+	igt_display_require_output(&data->display);
+}
+
+int main(int argc, char **argv)
+{
+	data_t data;
+	int option;
+	static const char optstr[] = "hied";
+	struct option long_opts[] = {
+		{"help",	no_argument,	NULL, 'h'},
+		{"info",	no_argument,	NULL, 'i'},
+		{"enable",	no_argument,	NULL, 'e'},
+		{"disable",	no_argument,	NULL, 'd'},
+		{NULL,		0,		NULL,  0 }
+	};
+
+	test_init(&data);
+
+	while ((option = getopt_long(argc, argv, optstr, long_opts, NULL)) != -1) {
+		switch (option) {
+		case 'i':
+			get_hdcp_info(&data);
+			break;
+		case 'e':
+			enable_hdcp();
+			break;
+		case 'd':
+			disable_hdcp();
+			break;
+		case 'h':
+		default:
+			print_usage();
+			break;
+		}
+	}
+}
diff --git a/tools/meson.build b/tools/meson.build
index de866c392..8185ba160 100644
--- a/tools/meson.build
+++ b/tools/meson.build
@@ -30,6 +30,7 @@ tools_progs = [
 	'intel_gpu_time',
 	'intel_gtt',
 	'intel_guc_logger',
+	'intel_hdcp',
 	'intel_infoframes',
 	'intel_lid',
 	'intel_opregion_decode',
-- 
2.34.1



More information about the igt-dev mailing list