[PATCH i-g-t v3 2/2] tools/intel_hdcp: Support for enabling and disabling HDCP

Santhosh Reddy Guddati santhosh.reddy.guddati at intel.com
Wed May 14 09:02:30 UTC 2025


Introduce support for enabling and disabling HDCP on specific connectors
using command line options.

Signed-off-by: Santhosh Reddy Guddati <santhosh.reddy.guddati at intel.com>
---
 tools/intel_hdcp.c | 119 +++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 114 insertions(+), 5 deletions(-)

diff --git a/tools/intel_hdcp.c b/tools/intel_hdcp.c
index fa7855d6e..aa7b2a376 100644
--- a/tools/intel_hdcp.c
+++ b/tools/intel_hdcp.c
@@ -9,6 +9,15 @@
 #include "igt.h"
 
 #define MAX_HDCP_BUF_LEN	5000
+#define MAX_CONNECTORS		10
+
+#define CP_UNDESIRED		0
+#define CP_DESIRED		1
+#define CP_ENABLED		2
+
+/* Max time per authentication allowed = 6Sec */
+#define KERNEL_AUTH_TIME_ALLOWED_MSEC		(6 * 1000)
+#define KERNEL_DISABLE_TIME_ALLOWED_MSEC	(1 * 1000)
 
 typedef struct data {
 	int fd;
@@ -17,6 +26,87 @@ typedef struct data {
 	int height, width;
 } data_t;
 
+static void update_display(data_t *data, igt_output_t *output, bool is_enabled)
+{
+	igt_display_t *display = &data->display;
+	igt_plane_t *primary;
+	drmModeModeInfo *mode;
+
+	mode = igt_output_get_mode(output);
+	data->height = mode->vdisplay;
+	data->width = mode->hdisplay;
+
+	igt_output_set_pipe(output, PIPE_A);
+	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
+
+	igt_create_color_fb(data->fd, data->width, data->height,
+			    DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
+			    1.f, 0.f, 0.f, &data->red);
+	igt_create_color_fb(data->fd, data->width, data->height,
+			    DRM_FORMAT_XRGB8888, DRM_FORMAT_MOD_LINEAR,
+			    0.f, 1.f, 0.f, &data->green);
+
+	if (is_enabled)
+		igt_plane_set_fb(primary, &data->green);
+	else
+		igt_plane_set_fb(primary, &data->red);
+
+	igt_display_commit2(display, COMMIT_ATOMIC);
+
+	igt_plane_set_fb(primary, NULL);
+	igt_remove_fb(data->fd, &data->red);
+	igt_remove_fb(data->fd, &data->green);
+	igt_output_set_pipe(output, PIPE_NONE);
+	igt_display_commit2(display, COMMIT_ATOMIC);
+}
+
+static void igt_output_set_hdcp(data_t *data, igt_output_t *output, bool enable)
+{
+	uint64_t prop_value;
+
+	igt_output_set_prop_value(output, IGT_CONNECTOR_CONTENT_PROTECTION,
+				enable ? CP_DESIRED : CP_UNDESIRED);
+
+	if (enable) {
+		usleep(KERNEL_AUTH_TIME_ALLOWED_MSEC);
+		prop_value = igt_output_get_prop(output, IGT_CONNECTOR_CONTENT_PROTECTION);
+
+		if (prop_value == CP_ENABLED) {
+			fprintf(stderr, "HDCP enabled on output %s\n", output->name);
+			update_display(data, output, true);
+		} else {
+			update_display(data, output, false);
+			fprintf(stderr, "Failed to enable HDCP on connector %s\n", output->name);
+		}
+	} else {
+		usleep(KERNEL_DISABLE_TIME_ALLOWED_MSEC);
+		prop_value = igt_output_get_prop(output, IGT_CONNECTOR_CONTENT_PROTECTION);
+
+		if (prop_value == CP_UNDESIRED) {
+			update_display(data, output, true);
+			fprintf(stderr, "HDCP disabled on connector %s\n", output->name);
+		} else {
+			update_display(data, output, false);
+			fprintf(stderr, "Failed to disable HDCP on connector %s\n", output->name);
+		}
+	}
+}
+
+static void set_hdcp(data_t *data, int connector_id, bool enable)
+{
+	igt_output_t *output;
+	drmModeConnector connector;
+
+	connector.connector_id = connector_id;
+	output = igt_output_from_connector(&data->display, &connector);
+	if (!output) {
+		fprintf(stderr, "Failed to get output for connector %d\n", connector_id);
+		return;
+	}
+
+	igt_output_set_hdcp(data, output, enable);
+}
+
 static const char *get_hdcp_version(int fd, char *connector_name)
 {
 	char buf[MAX_HDCP_BUF_LEN];
@@ -85,7 +175,8 @@ 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, "-h,	--help		Display this help message\n");
+	fprintf(stderr, "-e,	--enable	Enable HDCP on the specified connector id\n");
+	fprintf(stderr, "-d,	--disable	Disable HDCP on the specified connector id\n");
 }
 
 static void test_init(data_t *data)
@@ -103,11 +194,13 @@ int main(int argc, char **argv)
 {
 	data_t data;
 	int option;
-	static const char optstr[] = "hi";
+	static const char optstr[] = "hied:";
 	struct option long_opts[] = {
-		{"help",	no_argument,	NULL, 'h'},
-		{"info",	no_argument,	NULL, 'i'},
-		{NULL,		0,		NULL,  0 }
+		{"help",	no_argument,		NULL,	'h'},
+		{"info",	no_argument,		NULL,	'i'},
+		{"enable",	required_argument,	NULL,	'e'},
+		{"disable",	required_argument,	NULL,	'd'},
+		{NULL,		0,			NULL,	 0 }
 	};
 
 	test_init(&data);
@@ -117,6 +210,22 @@ int main(int argc, char **argv)
 		case 'i':
 			get_hdcp_info(&data);
 			break;
+		case 'e':
+			if (!optarg) {
+				fprintf(stderr, "Missing connector ID for enable\n");
+				print_usage();
+				exit(EXIT_FAILURE);
+			}
+			set_hdcp(&data, atoi(optarg), true);
+			break;
+		case 'd':
+			if (!optarg) {
+				fprintf(stderr, "Missing connector ID for enable\n");
+				print_usage();
+				exit(EXIT_FAILURE);
+			}
+			set_hdcp(&data, atoi(optarg), false);
+			break;
 		case 'h':
 		default:
 			print_usage();
-- 
2.34.1



More information about the igt-dev mailing list