xref: /aosp_15_r20/external/igt-gpu-tools/tests/kms_content_protection.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2018 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  */
24*d83cc019SAndroid Build Coastguard Worker 
25*d83cc019SAndroid Build Coastguard Worker #include <poll.h>
26*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
27*d83cc019SAndroid Build Coastguard Worker #include <sys/epoll.h>
28*d83cc019SAndroid Build Coastguard Worker #include <sys/stat.h>
29*d83cc019SAndroid Build Coastguard Worker #include <libudev.h>
30*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
31*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
32*d83cc019SAndroid Build Coastguard Worker #include "igt_kms.h"
33*d83cc019SAndroid Build Coastguard Worker #include "igt_kmod.h"
34*d83cc019SAndroid Build Coastguard Worker 
35*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Test content protection (HDCP)");
36*d83cc019SAndroid Build Coastguard Worker 
37*d83cc019SAndroid Build Coastguard Worker struct data {
38*d83cc019SAndroid Build Coastguard Worker 	int drm_fd;
39*d83cc019SAndroid Build Coastguard Worker 	igt_display_t display;
40*d83cc019SAndroid Build Coastguard Worker 	struct igt_fb red, green;
41*d83cc019SAndroid Build Coastguard Worker 	unsigned int cp_tests;
42*d83cc019SAndroid Build Coastguard Worker } data;
43*d83cc019SAndroid Build Coastguard Worker 
44*d83cc019SAndroid Build Coastguard Worker /* Test flags */
45*d83cc019SAndroid Build Coastguard Worker #define CP_DPMS					(1 << 0)
46*d83cc019SAndroid Build Coastguard Worker #define CP_LIC					(1 << 1)
47*d83cc019SAndroid Build Coastguard Worker #define CP_MEI_RELOAD				(1 << 2)
48*d83cc019SAndroid Build Coastguard Worker #define CP_TYPE_CHANGE				(1 << 3)
49*d83cc019SAndroid Build Coastguard Worker #define CP_UEVENT				(1 << 4)
50*d83cc019SAndroid Build Coastguard Worker 
51*d83cc019SAndroid Build Coastguard Worker #define CP_UNDESIRED				0
52*d83cc019SAndroid Build Coastguard Worker #define CP_DESIRED				1
53*d83cc019SAndroid Build Coastguard Worker #define CP_ENABLED				2
54*d83cc019SAndroid Build Coastguard Worker 
55*d83cc019SAndroid Build Coastguard Worker /*
56*d83cc019SAndroid Build Coastguard Worker  * HDCP_CONTENT_TYPE_0 can be handled on both HDCP1.4 and HDCP2.2. Where as
57*d83cc019SAndroid Build Coastguard Worker  * HDCP_CONTENT_TYPE_1 can be handled only through HDCP2.2.
58*d83cc019SAndroid Build Coastguard Worker  */
59*d83cc019SAndroid Build Coastguard Worker #define HDCP_CONTENT_TYPE_0				0
60*d83cc019SAndroid Build Coastguard Worker #define HDCP_CONTENT_TYPE_1				1
61*d83cc019SAndroid Build Coastguard Worker 
62*d83cc019SAndroid Build Coastguard Worker #define LIC_PERIOD_MSEC				(4 * 1000)
63*d83cc019SAndroid Build Coastguard Worker /* Kernel retry count=3, Max time per authentication allowed = 6Sec */
64*d83cc019SAndroid Build Coastguard Worker #define KERNEL_AUTH_TIME_ALLOWED_MSEC		(3 *  6 * 1000)
65*d83cc019SAndroid Build Coastguard Worker #define KERNEL_DISABLE_TIME_ALLOWED_MSEC	(1 * 1000)
66*d83cc019SAndroid Build Coastguard Worker #define FLIP_EVENT_POLLING_TIMEOUT_MSEC		1000
67*d83cc019SAndroid Build Coastguard Worker 
68*d83cc019SAndroid Build Coastguard Worker __u8 facsimile_srm[] = {
69*d83cc019SAndroid Build Coastguard Worker 	0x80, 0x0, 0x0, 0x05, 0x01, 0x0, 0x0, 0x36, 0x02, 0x51, 0x1E, 0xF2,
70*d83cc019SAndroid Build Coastguard Worker 	0x1A, 0xCD, 0xE7, 0x26, 0x97, 0xF4, 0x01, 0x97, 0x10, 0x19, 0x92, 0x53,
71*d83cc019SAndroid Build Coastguard Worker 	0xE9, 0xF0, 0x59, 0x95, 0xA3, 0x7A, 0x3B, 0xFE, 0xE0, 0x9C, 0x76, 0xDD,
72*d83cc019SAndroid Build Coastguard Worker 	0x83, 0xAA, 0xC2, 0x5B, 0x24, 0xB3, 0x36, 0x84, 0x94, 0x75, 0x34, 0xDB,
73*d83cc019SAndroid Build Coastguard Worker 	0x10, 0x9E, 0x3B, 0x23, 0x13, 0xD8, 0x7A, 0xC2, 0x30, 0x79, 0x84};
74*d83cc019SAndroid Build Coastguard Worker 
flip_handler(int fd,unsigned int sequence,unsigned int tv_sec,unsigned int tv_usec,void * _data)75*d83cc019SAndroid Build Coastguard Worker static void flip_handler(int fd, unsigned int sequence, unsigned int tv_sec,
76*d83cc019SAndroid Build Coastguard Worker 			 unsigned int tv_usec, void *_data)
77*d83cc019SAndroid Build Coastguard Worker {
78*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Flip event received.\n");
79*d83cc019SAndroid Build Coastguard Worker }
80*d83cc019SAndroid Build Coastguard Worker 
wait_flip_event(void)81*d83cc019SAndroid Build Coastguard Worker static int wait_flip_event(void)
82*d83cc019SAndroid Build Coastguard Worker {
83*d83cc019SAndroid Build Coastguard Worker 	int rc;
84*d83cc019SAndroid Build Coastguard Worker 	drmEventContext evctx;
85*d83cc019SAndroid Build Coastguard Worker 	struct pollfd pfd;
86*d83cc019SAndroid Build Coastguard Worker 
87*d83cc019SAndroid Build Coastguard Worker 	evctx.version = 2;
88*d83cc019SAndroid Build Coastguard Worker 	evctx.vblank_handler = NULL;
89*d83cc019SAndroid Build Coastguard Worker 	evctx.page_flip_handler = flip_handler;
90*d83cc019SAndroid Build Coastguard Worker 
91*d83cc019SAndroid Build Coastguard Worker 	pfd.fd = data.drm_fd;
92*d83cc019SAndroid Build Coastguard Worker 	pfd.events = POLLIN;
93*d83cc019SAndroid Build Coastguard Worker 	pfd.revents = 0;
94*d83cc019SAndroid Build Coastguard Worker 
95*d83cc019SAndroid Build Coastguard Worker 	rc = poll(&pfd, 1, FLIP_EVENT_POLLING_TIMEOUT_MSEC);
96*d83cc019SAndroid Build Coastguard Worker 	switch (rc) {
97*d83cc019SAndroid Build Coastguard Worker 	case 0:
98*d83cc019SAndroid Build Coastguard Worker 		igt_info("Poll timeout. 1Sec.\n");
99*d83cc019SAndroid Build Coastguard Worker 		rc = -ETIMEDOUT;
100*d83cc019SAndroid Build Coastguard Worker 		break;
101*d83cc019SAndroid Build Coastguard Worker 	case 1:
102*d83cc019SAndroid Build Coastguard Worker 		rc = drmHandleEvent(data.drm_fd, &evctx);
103*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(rc, 0);
104*d83cc019SAndroid Build Coastguard Worker 		rc = 0;
105*d83cc019SAndroid Build Coastguard Worker 		break;
106*d83cc019SAndroid Build Coastguard Worker 	default:
107*d83cc019SAndroid Build Coastguard Worker 		igt_info("Unexpected poll rc %d\n", rc);
108*d83cc019SAndroid Build Coastguard Worker 		rc = -1;
109*d83cc019SAndroid Build Coastguard Worker 		break;
110*d83cc019SAndroid Build Coastguard Worker 	}
111*d83cc019SAndroid Build Coastguard Worker 
112*d83cc019SAndroid Build Coastguard Worker 	return rc;
113*d83cc019SAndroid Build Coastguard Worker }
114*d83cc019SAndroid Build Coastguard Worker 
hdcp_event(struct udev_monitor * uevent_monitor,struct udev * udev,uint32_t conn_id,uint32_t prop_id)115*d83cc019SAndroid Build Coastguard Worker static bool hdcp_event(struct udev_monitor *uevent_monitor,
116*d83cc019SAndroid Build Coastguard Worker 		       struct udev *udev, uint32_t conn_id, uint32_t prop_id)
117*d83cc019SAndroid Build Coastguard Worker {
118*d83cc019SAndroid Build Coastguard Worker 	struct udev_device *dev;
119*d83cc019SAndroid Build Coastguard Worker 	dev_t udev_devnum;
120*d83cc019SAndroid Build Coastguard Worker 	struct stat s;
121*d83cc019SAndroid Build Coastguard Worker 	const char *hotplug, *connector, *property;
122*d83cc019SAndroid Build Coastguard Worker 	bool ret = false;
123*d83cc019SAndroid Build Coastguard Worker 
124*d83cc019SAndroid Build Coastguard Worker 	dev = udev_monitor_receive_device(uevent_monitor);
125*d83cc019SAndroid Build Coastguard Worker 	if (!dev)
126*d83cc019SAndroid Build Coastguard Worker 		goto out;
127*d83cc019SAndroid Build Coastguard Worker 
128*d83cc019SAndroid Build Coastguard Worker 	udev_devnum = udev_device_get_devnum(dev);
129*d83cc019SAndroid Build Coastguard Worker 	fstat(data.display.drm_fd, &s);
130*d83cc019SAndroid Build Coastguard Worker 
131*d83cc019SAndroid Build Coastguard Worker 	hotplug = udev_device_get_property_value(dev, "HOTPLUG");
132*d83cc019SAndroid Build Coastguard Worker 	if (!(memcmp(&s.st_rdev, &udev_devnum, sizeof(dev_t)) == 0 &&
133*d83cc019SAndroid Build Coastguard Worker 	    hotplug && atoi(hotplug) == 1)) {
134*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Not a Hotplug event\n");
135*d83cc019SAndroid Build Coastguard Worker 		goto out_dev;
136*d83cc019SAndroid Build Coastguard Worker 	}
137*d83cc019SAndroid Build Coastguard Worker 
138*d83cc019SAndroid Build Coastguard Worker 	connector = udev_device_get_property_value(dev, "CONNECTOR");
139*d83cc019SAndroid Build Coastguard Worker 	if (!(memcmp(&s.st_rdev, &udev_devnum, sizeof(dev_t)) == 0 &&
140*d83cc019SAndroid Build Coastguard Worker 	    connector && atoi(connector) == conn_id)) {
141*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Not for connector id: %u\n", conn_id);
142*d83cc019SAndroid Build Coastguard Worker 		goto out_dev;
143*d83cc019SAndroid Build Coastguard Worker 	}
144*d83cc019SAndroid Build Coastguard Worker 
145*d83cc019SAndroid Build Coastguard Worker 	property = udev_device_get_property_value(dev, "PROPERTY");
146*d83cc019SAndroid Build Coastguard Worker 	if (!(memcmp(&s.st_rdev, &udev_devnum, sizeof(dev_t)) == 0 &&
147*d83cc019SAndroid Build Coastguard Worker 	    property && atoi(property) == prop_id)) {
148*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Not for property id: %u\n", prop_id);
149*d83cc019SAndroid Build Coastguard Worker 		goto out_dev;
150*d83cc019SAndroid Build Coastguard Worker 	}
151*d83cc019SAndroid Build Coastguard Worker 	ret = true;
152*d83cc019SAndroid Build Coastguard Worker 
153*d83cc019SAndroid Build Coastguard Worker out_dev:
154*d83cc019SAndroid Build Coastguard Worker 	udev_device_unref(dev);
155*d83cc019SAndroid Build Coastguard Worker out:
156*d83cc019SAndroid Build Coastguard Worker 	return ret;
157*d83cc019SAndroid Build Coastguard Worker }
158*d83cc019SAndroid Build Coastguard Worker 
hdcp_udev_fini(struct udev_monitor * uevent_monitor,struct udev * udev)159*d83cc019SAndroid Build Coastguard Worker static void hdcp_udev_fini(struct udev_monitor *uevent_monitor,
160*d83cc019SAndroid Build Coastguard Worker 			   struct udev *udev)
161*d83cc019SAndroid Build Coastguard Worker {
162*d83cc019SAndroid Build Coastguard Worker 	if (uevent_monitor)
163*d83cc019SAndroid Build Coastguard Worker 		udev_monitor_unref(uevent_monitor);
164*d83cc019SAndroid Build Coastguard Worker 	if (udev)
165*d83cc019SAndroid Build Coastguard Worker 		udev_unref(udev);
166*d83cc019SAndroid Build Coastguard Worker }
167*d83cc019SAndroid Build Coastguard Worker 
hdcp_udev_init(struct udev_monitor * uevent_monitor,struct udev * udev)168*d83cc019SAndroid Build Coastguard Worker static int hdcp_udev_init(struct udev_monitor *uevent_monitor,
169*d83cc019SAndroid Build Coastguard Worker 			  struct udev *udev)
170*d83cc019SAndroid Build Coastguard Worker {
171*d83cc019SAndroid Build Coastguard Worker 	int ret = -EINVAL;
172*d83cc019SAndroid Build Coastguard Worker 
173*d83cc019SAndroid Build Coastguard Worker 	udev = udev_new();
174*d83cc019SAndroid Build Coastguard Worker 	if (!udev) {
175*d83cc019SAndroid Build Coastguard Worker 		igt_info("failed to create udev object\n");
176*d83cc019SAndroid Build Coastguard Worker 		goto out;
177*d83cc019SAndroid Build Coastguard Worker 	}
178*d83cc019SAndroid Build Coastguard Worker 
179*d83cc019SAndroid Build Coastguard Worker 	uevent_monitor = udev_monitor_new_from_netlink(udev, "udev");
180*d83cc019SAndroid Build Coastguard Worker 	if (!uevent_monitor) {
181*d83cc019SAndroid Build Coastguard Worker 		igt_info("failed to create udev event monitor\n");
182*d83cc019SAndroid Build Coastguard Worker 		goto out;
183*d83cc019SAndroid Build Coastguard Worker 	}
184*d83cc019SAndroid Build Coastguard Worker 
185*d83cc019SAndroid Build Coastguard Worker 	ret = udev_monitor_filter_add_match_subsystem_devtype(uevent_monitor,
186*d83cc019SAndroid Build Coastguard Worker 							      "drm",
187*d83cc019SAndroid Build Coastguard Worker 							      "drm_minor");
188*d83cc019SAndroid Build Coastguard Worker 	if (ret < 0) {
189*d83cc019SAndroid Build Coastguard Worker 		igt_info("failed to filter for drm events\n");
190*d83cc019SAndroid Build Coastguard Worker 		goto out;
191*d83cc019SAndroid Build Coastguard Worker 	}
192*d83cc019SAndroid Build Coastguard Worker 
193*d83cc019SAndroid Build Coastguard Worker 	ret = udev_monitor_enable_receiving(uevent_monitor);
194*d83cc019SAndroid Build Coastguard Worker 	if (ret < 0) {
195*d83cc019SAndroid Build Coastguard Worker 		igt_info("failed to enable udev event reception\n");
196*d83cc019SAndroid Build Coastguard Worker 		goto out;
197*d83cc019SAndroid Build Coastguard Worker 	}
198*d83cc019SAndroid Build Coastguard Worker 
199*d83cc019SAndroid Build Coastguard Worker 	return udev_monitor_get_fd(uevent_monitor);
200*d83cc019SAndroid Build Coastguard Worker 
201*d83cc019SAndroid Build Coastguard Worker out:
202*d83cc019SAndroid Build Coastguard Worker 	hdcp_udev_fini(uevent_monitor, udev);
203*d83cc019SAndroid Build Coastguard Worker 	return ret;
204*d83cc019SAndroid Build Coastguard Worker }
205*d83cc019SAndroid Build Coastguard Worker 
206*d83cc019SAndroid Build Coastguard Worker #define MAX_EVENTS	10
wait_for_hdcp_event(uint32_t conn_id,uint32_t prop_id,uint32_t timeout_mSec)207*d83cc019SAndroid Build Coastguard Worker static bool wait_for_hdcp_event(uint32_t conn_id, uint32_t prop_id,
208*d83cc019SAndroid Build Coastguard Worker 				uint32_t timeout_mSec)
209*d83cc019SAndroid Build Coastguard Worker {
210*d83cc019SAndroid Build Coastguard Worker 
211*d83cc019SAndroid Build Coastguard Worker 	struct udev_monitor *uevent_monitor = NULL;
212*d83cc019SAndroid Build Coastguard Worker 	struct udev *udev = NULL;
213*d83cc019SAndroid Build Coastguard Worker 	int udev_fd, epoll_fd;
214*d83cc019SAndroid Build Coastguard Worker 	struct epoll_event event, events[MAX_EVENTS];
215*d83cc019SAndroid Build Coastguard Worker 	bool ret = false;
216*d83cc019SAndroid Build Coastguard Worker 
217*d83cc019SAndroid Build Coastguard Worker 	udev_fd = hdcp_udev_init(uevent_monitor, udev);
218*d83cc019SAndroid Build Coastguard Worker 	if (udev_fd < 0)
219*d83cc019SAndroid Build Coastguard Worker 		return false;
220*d83cc019SAndroid Build Coastguard Worker 
221*d83cc019SAndroid Build Coastguard Worker 	epoll_fd = epoll_create1(0);
222*d83cc019SAndroid Build Coastguard Worker 	if (epoll_fd == -1) {
223*d83cc019SAndroid Build Coastguard Worker 		igt_info("Failed to create epoll fd. %d\n", epoll_fd);
224*d83cc019SAndroid Build Coastguard Worker 		goto out_ep_create;
225*d83cc019SAndroid Build Coastguard Worker 	}
226*d83cc019SAndroid Build Coastguard Worker 
227*d83cc019SAndroid Build Coastguard Worker 	event.events = EPOLLIN | EPOLLERR;
228*d83cc019SAndroid Build Coastguard Worker 	event.data.fd = 0;
229*d83cc019SAndroid Build Coastguard Worker 
230*d83cc019SAndroid Build Coastguard Worker 	if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, udev_fd, &event)) {
231*d83cc019SAndroid Build Coastguard Worker 		igt_info("failed to fd into epoll\n");
232*d83cc019SAndroid Build Coastguard Worker 		goto out_ep_ctl;
233*d83cc019SAndroid Build Coastguard Worker 	}
234*d83cc019SAndroid Build Coastguard Worker 
235*d83cc019SAndroid Build Coastguard Worker 	if (epoll_wait(epoll_fd, events, MAX_EVENTS, timeout_mSec))
236*d83cc019SAndroid Build Coastguard Worker 		ret = hdcp_event(uevent_monitor, udev, conn_id, prop_id);
237*d83cc019SAndroid Build Coastguard Worker 
238*d83cc019SAndroid Build Coastguard Worker out_ep_ctl:
239*d83cc019SAndroid Build Coastguard Worker 	if (close(epoll_fd))
240*d83cc019SAndroid Build Coastguard Worker 		igt_info("failed to close the epoll fd\n");
241*d83cc019SAndroid Build Coastguard Worker out_ep_create:
242*d83cc019SAndroid Build Coastguard Worker 	hdcp_udev_fini(uevent_monitor, udev);
243*d83cc019SAndroid Build Coastguard Worker 	return ret;
244*d83cc019SAndroid Build Coastguard Worker }
245*d83cc019SAndroid Build Coastguard Worker 
246*d83cc019SAndroid Build Coastguard Worker static bool
wait_for_prop_value(igt_output_t * output,uint64_t expected,uint32_t timeout_mSec)247*d83cc019SAndroid Build Coastguard Worker wait_for_prop_value(igt_output_t *output, uint64_t expected,
248*d83cc019SAndroid Build Coastguard Worker 		    uint32_t timeout_mSec)
249*d83cc019SAndroid Build Coastguard Worker {
250*d83cc019SAndroid Build Coastguard Worker 	uint64_t val;
251*d83cc019SAndroid Build Coastguard Worker 	int i;
252*d83cc019SAndroid Build Coastguard Worker 
253*d83cc019SAndroid Build Coastguard Worker 	if (data.cp_tests & CP_UEVENT && expected != CP_UNDESIRED) {
254*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(wait_for_hdcp_event(output->id,
255*d83cc019SAndroid Build Coastguard Worker 			     output->props[IGT_CONNECTOR_CONTENT_PROTECTION],
256*d83cc019SAndroid Build Coastguard Worker 			     timeout_mSec), "uevent is not received");
257*d83cc019SAndroid Build Coastguard Worker 
258*d83cc019SAndroid Build Coastguard Worker 		val = igt_output_get_prop(output,
259*d83cc019SAndroid Build Coastguard Worker 					  IGT_CONNECTOR_CONTENT_PROTECTION);
260*d83cc019SAndroid Build Coastguard Worker 		if (val == expected)
261*d83cc019SAndroid Build Coastguard Worker 			return true;
262*d83cc019SAndroid Build Coastguard Worker 	} else {
263*d83cc019SAndroid Build Coastguard Worker 		for (i = 0; i < timeout_mSec; i++) {
264*d83cc019SAndroid Build Coastguard Worker 			val = igt_output_get_prop(output,
265*d83cc019SAndroid Build Coastguard Worker 						  IGT_CONNECTOR_CONTENT_PROTECTION);
266*d83cc019SAndroid Build Coastguard Worker 			if (val == expected)
267*d83cc019SAndroid Build Coastguard Worker 				return true;
268*d83cc019SAndroid Build Coastguard Worker 			usleep(1000);
269*d83cc019SAndroid Build Coastguard Worker 		}
270*d83cc019SAndroid Build Coastguard Worker 	}
271*d83cc019SAndroid Build Coastguard Worker 
272*d83cc019SAndroid Build Coastguard Worker 	igt_info("prop_value mismatch %" PRId64 " != %" PRId64 "\n",
273*d83cc019SAndroid Build Coastguard Worker 		 val, expected);
274*d83cc019SAndroid Build Coastguard Worker 
275*d83cc019SAndroid Build Coastguard Worker 	return false;
276*d83cc019SAndroid Build Coastguard Worker }
277*d83cc019SAndroid Build Coastguard Worker 
278*d83cc019SAndroid Build Coastguard Worker static void
commit_display_and_wait_for_flip(enum igt_commit_style s)279*d83cc019SAndroid Build Coastguard Worker commit_display_and_wait_for_flip(enum igt_commit_style s)
280*d83cc019SAndroid Build Coastguard Worker {
281*d83cc019SAndroid Build Coastguard Worker 	int ret;
282*d83cc019SAndroid Build Coastguard Worker 	uint32_t flag;
283*d83cc019SAndroid Build Coastguard Worker 
284*d83cc019SAndroid Build Coastguard Worker 	if (s == COMMIT_ATOMIC) {
285*d83cc019SAndroid Build Coastguard Worker 		flag = DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_ALLOW_MODESET;
286*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit_atomic(&data.display, flag, NULL);
287*d83cc019SAndroid Build Coastguard Worker 
288*d83cc019SAndroid Build Coastguard Worker 		ret = wait_flip_event();
289*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(!ret, "wait_flip_event failed. %d\n", ret);
290*d83cc019SAndroid Build Coastguard Worker 	} else {
291*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(&data.display, s);
292*d83cc019SAndroid Build Coastguard Worker 
293*d83cc019SAndroid Build Coastguard Worker 		/* Wait for 50mSec */
294*d83cc019SAndroid Build Coastguard Worker 		usleep(50 * 1000);
295*d83cc019SAndroid Build Coastguard Worker 	}
296*d83cc019SAndroid Build Coastguard Worker }
297*d83cc019SAndroid Build Coastguard Worker 
modeset_with_fb(const enum pipe pipe,igt_output_t * output,enum igt_commit_style s)298*d83cc019SAndroid Build Coastguard Worker static void modeset_with_fb(const enum pipe pipe, igt_output_t *output,
299*d83cc019SAndroid Build Coastguard Worker 			    enum igt_commit_style s)
300*d83cc019SAndroid Build Coastguard Worker {
301*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data.display;
302*d83cc019SAndroid Build Coastguard Worker 	drmModeModeInfo mode;
303*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
304*d83cc019SAndroid Build Coastguard Worker 
305*d83cc019SAndroid Build Coastguard Worker 	igt_assert(kmstest_get_connector_default_mode(
306*d83cc019SAndroid Build Coastguard Worker 			display->drm_fd, output->config.connector, &mode));
307*d83cc019SAndroid Build Coastguard Worker 
308*d83cc019SAndroid Build Coastguard Worker 	igt_output_override_mode(output, &mode);
309*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_pipe(output, pipe);
310*d83cc019SAndroid Build Coastguard Worker 
311*d83cc019SAndroid Build Coastguard Worker 	igt_create_color_fb(display->drm_fd, mode.hdisplay, mode.vdisplay,
312*d83cc019SAndroid Build Coastguard Worker 			    DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
313*d83cc019SAndroid Build Coastguard Worker 			    1.f, 0.f, 0.f, &data.red);
314*d83cc019SAndroid Build Coastguard Worker 	igt_create_color_fb(display->drm_fd, mode.hdisplay, mode.vdisplay,
315*d83cc019SAndroid Build Coastguard Worker 			    DRM_FORMAT_XRGB8888, LOCAL_DRM_FORMAT_MOD_NONE,
316*d83cc019SAndroid Build Coastguard Worker 			    0.f, 1.f, 0.f, &data.green);
317*d83cc019SAndroid Build Coastguard Worker 
318*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
319*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(display, s);
320*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, &data.red);
321*d83cc019SAndroid Build Coastguard Worker 
322*d83cc019SAndroid Build Coastguard Worker 	/* Wait for Flip completion before starting the HDCP authentication */
323*d83cc019SAndroid Build Coastguard Worker 	commit_display_and_wait_for_flip(s);
324*d83cc019SAndroid Build Coastguard Worker }
325*d83cc019SAndroid Build Coastguard Worker 
test_cp_enable(igt_output_t * output,enum igt_commit_style s,int content_type,bool type_change)326*d83cc019SAndroid Build Coastguard Worker static bool test_cp_enable(igt_output_t *output, enum igt_commit_style s,
327*d83cc019SAndroid Build Coastguard Worker 			   int content_type, bool type_change)
328*d83cc019SAndroid Build Coastguard Worker {
329*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data.display;
330*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
331*d83cc019SAndroid Build Coastguard Worker 	bool ret;
332*d83cc019SAndroid Build Coastguard Worker 
333*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
334*d83cc019SAndroid Build Coastguard Worker 
335*d83cc019SAndroid Build Coastguard Worker 	if (!type_change)
336*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_prop_value(output,
337*d83cc019SAndroid Build Coastguard Worker 					  IGT_CONNECTOR_CONTENT_PROTECTION,
338*d83cc019SAndroid Build Coastguard Worker 					  CP_DESIRED);
339*d83cc019SAndroid Build Coastguard Worker 
340*d83cc019SAndroid Build Coastguard Worker 	if (output->props[IGT_CONNECTOR_HDCP_CONTENT_TYPE])
341*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_prop_value(output,
342*d83cc019SAndroid Build Coastguard Worker 					  IGT_CONNECTOR_HDCP_CONTENT_TYPE,
343*d83cc019SAndroid Build Coastguard Worker 					  content_type);
344*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(display, s);
345*d83cc019SAndroid Build Coastguard Worker 
346*d83cc019SAndroid Build Coastguard Worker 	ret = wait_for_prop_value(output, CP_ENABLED,
347*d83cc019SAndroid Build Coastguard Worker 				  KERNEL_AUTH_TIME_ALLOWED_MSEC);
348*d83cc019SAndroid Build Coastguard Worker 	if (ret) {
349*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(primary, &data.green);
350*d83cc019SAndroid Build Coastguard Worker 		igt_display_commit2(display, s);
351*d83cc019SAndroid Build Coastguard Worker 	}
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker 	return ret;
354*d83cc019SAndroid Build Coastguard Worker }
355*d83cc019SAndroid Build Coastguard Worker 
test_cp_disable(igt_output_t * output,enum igt_commit_style s)356*d83cc019SAndroid Build Coastguard Worker static void test_cp_disable(igt_output_t *output, enum igt_commit_style s)
357*d83cc019SAndroid Build Coastguard Worker {
358*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data.display;
359*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
360*d83cc019SAndroid Build Coastguard Worker 	bool ret;
361*d83cc019SAndroid Build Coastguard Worker 
362*d83cc019SAndroid Build Coastguard Worker 	primary = igt_output_get_plane_type(output, DRM_PLANE_TYPE_PRIMARY);
363*d83cc019SAndroid Build Coastguard Worker 
364*d83cc019SAndroid Build Coastguard Worker 	/*
365*d83cc019SAndroid Build Coastguard Worker 	 * Even on HDCP enable failed scenario, IGT should exit leaving the
366*d83cc019SAndroid Build Coastguard Worker 	 * "content protection" at "UNDESIRED".
367*d83cc019SAndroid Build Coastguard Worker 	 */
368*d83cc019SAndroid Build Coastguard Worker 	igt_output_set_prop_value(output, IGT_CONNECTOR_CONTENT_PROTECTION,
369*d83cc019SAndroid Build Coastguard Worker 				  CP_UNDESIRED);
370*d83cc019SAndroid Build Coastguard Worker 	igt_plane_set_fb(primary, &data.red);
371*d83cc019SAndroid Build Coastguard Worker 	igt_display_commit2(display, s);
372*d83cc019SAndroid Build Coastguard Worker 
373*d83cc019SAndroid Build Coastguard Worker 	/* Wait for HDCP to be disabled, before crtc off */
374*d83cc019SAndroid Build Coastguard Worker 	ret = wait_for_prop_value(output, CP_UNDESIRED,
375*d83cc019SAndroid Build Coastguard Worker 				  KERNEL_DISABLE_TIME_ALLOWED_MSEC);
376*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(ret, "Content Protection not cleared\n");
377*d83cc019SAndroid Build Coastguard Worker }
378*d83cc019SAndroid Build Coastguard Worker 
test_cp_enable_with_retry(igt_output_t * output,enum igt_commit_style s,int retry,int content_type,bool expect_failure,bool type_change)379*d83cc019SAndroid Build Coastguard Worker static void test_cp_enable_with_retry(igt_output_t *output,
380*d83cc019SAndroid Build Coastguard Worker 				      enum igt_commit_style s, int retry,
381*d83cc019SAndroid Build Coastguard Worker 				      int content_type, bool expect_failure,
382*d83cc019SAndroid Build Coastguard Worker 				      bool type_change)
383*d83cc019SAndroid Build Coastguard Worker {
384*d83cc019SAndroid Build Coastguard Worker 	int retry_orig = retry;
385*d83cc019SAndroid Build Coastguard Worker 	bool ret;
386*d83cc019SAndroid Build Coastguard Worker 
387*d83cc019SAndroid Build Coastguard Worker 	do {
388*d83cc019SAndroid Build Coastguard Worker 		if (!type_change || retry_orig != retry)
389*d83cc019SAndroid Build Coastguard Worker 			test_cp_disable(output, s);
390*d83cc019SAndroid Build Coastguard Worker 
391*d83cc019SAndroid Build Coastguard Worker 		ret = test_cp_enable(output, s, content_type, type_change);
392*d83cc019SAndroid Build Coastguard Worker 
393*d83cc019SAndroid Build Coastguard Worker 		if (!ret && --retry)
394*d83cc019SAndroid Build Coastguard Worker 			igt_debug("Retry (%d/2) ...\n", 3 - retry);
395*d83cc019SAndroid Build Coastguard Worker 	} while (retry && !ret);
396*d83cc019SAndroid Build Coastguard Worker 
397*d83cc019SAndroid Build Coastguard Worker 	if (!ret)
398*d83cc019SAndroid Build Coastguard Worker 		test_cp_disable(output, s);
399*d83cc019SAndroid Build Coastguard Worker 
400*d83cc019SAndroid Build Coastguard Worker 	if (expect_failure)
401*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(!ret,
402*d83cc019SAndroid Build Coastguard Worker 			     "CP Enabled. Though it is expected to fail\n");
403*d83cc019SAndroid Build Coastguard Worker 	else
404*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(ret, "Content Protection not enabled\n");
405*d83cc019SAndroid Build Coastguard Worker 
406*d83cc019SAndroid Build Coastguard Worker }
407*d83cc019SAndroid Build Coastguard Worker 
igt_pipe_is_free(igt_display_t * display,enum pipe pipe)408*d83cc019SAndroid Build Coastguard Worker static bool igt_pipe_is_free(igt_display_t *display, enum pipe pipe)
409*d83cc019SAndroid Build Coastguard Worker {
410*d83cc019SAndroid Build Coastguard Worker 	int i;
411*d83cc019SAndroid Build Coastguard Worker 
412*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < display->n_outputs; i++)
413*d83cc019SAndroid Build Coastguard Worker 		if (display->outputs[i].pending_pipe == pipe)
414*d83cc019SAndroid Build Coastguard Worker 			return false;
415*d83cc019SAndroid Build Coastguard Worker 
416*d83cc019SAndroid Build Coastguard Worker 	return true;
417*d83cc019SAndroid Build Coastguard Worker }
418*d83cc019SAndroid Build Coastguard Worker 
test_cp_lic(igt_output_t * output)419*d83cc019SAndroid Build Coastguard Worker static void test_cp_lic(igt_output_t *output)
420*d83cc019SAndroid Build Coastguard Worker {
421*d83cc019SAndroid Build Coastguard Worker 	bool ret;
422*d83cc019SAndroid Build Coastguard Worker 
423*d83cc019SAndroid Build Coastguard Worker 	/* Wait for 4Secs (min 2 cycles of Link Integrity Check) */
424*d83cc019SAndroid Build Coastguard Worker 	ret = wait_for_prop_value(output, CP_DESIRED, LIC_PERIOD_MSEC);
425*d83cc019SAndroid Build Coastguard Worker 	igt_assert_f(!ret, "Content Protection LIC Failed\n");
426*d83cc019SAndroid Build Coastguard Worker }
427*d83cc019SAndroid Build Coastguard Worker 
write_srm_as_fw(const __u8 * srm,int len)428*d83cc019SAndroid Build Coastguard Worker static bool write_srm_as_fw(const __u8 *srm, int len)
429*d83cc019SAndroid Build Coastguard Worker {
430*d83cc019SAndroid Build Coastguard Worker 	int fd, ret, total = 0;
431*d83cc019SAndroid Build Coastguard Worker 
432*d83cc019SAndroid Build Coastguard Worker 	fd = open("/lib/firmware/display_hdcp_srm.bin",
433*d83cc019SAndroid Build Coastguard Worker 		  O_WRONLY | O_CREAT, S_IRWXU);
434*d83cc019SAndroid Build Coastguard Worker 	do {
435*d83cc019SAndroid Build Coastguard Worker 		ret = write(fd, srm + total, len - total);
436*d83cc019SAndroid Build Coastguard Worker 		if (ret < 0)
437*d83cc019SAndroid Build Coastguard Worker 			ret = -errno;
438*d83cc019SAndroid Build Coastguard Worker 		if (ret == -EINTR || ret == -EAGAIN)
439*d83cc019SAndroid Build Coastguard Worker 			continue;
440*d83cc019SAndroid Build Coastguard Worker 		if (ret <= 0)
441*d83cc019SAndroid Build Coastguard Worker 			break;
442*d83cc019SAndroid Build Coastguard Worker 		total += ret;
443*d83cc019SAndroid Build Coastguard Worker 	} while (total != len);
444*d83cc019SAndroid Build Coastguard Worker 	close(fd);
445*d83cc019SAndroid Build Coastguard Worker 
446*d83cc019SAndroid Build Coastguard Worker 	return total < len ? false : true;
447*d83cc019SAndroid Build Coastguard Worker }
448*d83cc019SAndroid Build Coastguard Worker 
test_content_protection_on_output(igt_output_t * output,enum igt_commit_style s,int content_type)449*d83cc019SAndroid Build Coastguard Worker static void test_content_protection_on_output(igt_output_t *output,
450*d83cc019SAndroid Build Coastguard Worker 					      enum igt_commit_style s,
451*d83cc019SAndroid Build Coastguard Worker 					      int content_type)
452*d83cc019SAndroid Build Coastguard Worker {
453*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data.display;
454*d83cc019SAndroid Build Coastguard Worker 	igt_plane_t *primary;
455*d83cc019SAndroid Build Coastguard Worker 	enum pipe pipe;
456*d83cc019SAndroid Build Coastguard Worker 	bool ret;
457*d83cc019SAndroid Build Coastguard Worker 
458*d83cc019SAndroid Build Coastguard Worker 	for_each_pipe(display, pipe) {
459*d83cc019SAndroid Build Coastguard Worker 		if (!igt_pipe_connector_valid(pipe, output))
460*d83cc019SAndroid Build Coastguard Worker 			continue;
461*d83cc019SAndroid Build Coastguard Worker 
462*d83cc019SAndroid Build Coastguard Worker 		/*
463*d83cc019SAndroid Build Coastguard Worker 		 * If previous subtest of connector failed, pipe
464*d83cc019SAndroid Build Coastguard Worker 		 * attached to that connector is not released.
465*d83cc019SAndroid Build Coastguard Worker 		 * Because of that we have to choose the non
466*d83cc019SAndroid Build Coastguard Worker 		 * attached pipe for this subtest.
467*d83cc019SAndroid Build Coastguard Worker 		 */
468*d83cc019SAndroid Build Coastguard Worker 		if (!igt_pipe_is_free(display, pipe))
469*d83cc019SAndroid Build Coastguard Worker 			continue;
470*d83cc019SAndroid Build Coastguard Worker 
471*d83cc019SAndroid Build Coastguard Worker 		modeset_with_fb(pipe, output, s);
472*d83cc019SAndroid Build Coastguard Worker 		test_cp_enable_with_retry(output, s, 3, content_type, false,
473*d83cc019SAndroid Build Coastguard Worker 					  false);
474*d83cc019SAndroid Build Coastguard Worker 
475*d83cc019SAndroid Build Coastguard Worker 		if (data.cp_tests & CP_TYPE_CHANGE) {
476*d83cc019SAndroid Build Coastguard Worker 			/* Type 1 -> Type 0 */
477*d83cc019SAndroid Build Coastguard Worker 			test_cp_enable_with_retry(output, s, 3,
478*d83cc019SAndroid Build Coastguard Worker 						  HDCP_CONTENT_TYPE_0, false,
479*d83cc019SAndroid Build Coastguard Worker 						  true);
480*d83cc019SAndroid Build Coastguard Worker 			/* Type 0 -> Type 1 */
481*d83cc019SAndroid Build Coastguard Worker 			test_cp_enable_with_retry(output, s, 3,
482*d83cc019SAndroid Build Coastguard Worker 						  content_type, false,
483*d83cc019SAndroid Build Coastguard Worker 						  true);
484*d83cc019SAndroid Build Coastguard Worker 		}
485*d83cc019SAndroid Build Coastguard Worker 
486*d83cc019SAndroid Build Coastguard Worker 		if (data.cp_tests & CP_MEI_RELOAD) {
487*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(!igt_kmod_unload("mei_hdcp", 0),
488*d83cc019SAndroid Build Coastguard Worker 				     "mei_hdcp unload failed");
489*d83cc019SAndroid Build Coastguard Worker 
490*d83cc019SAndroid Build Coastguard Worker 			/* Expected to fail */
491*d83cc019SAndroid Build Coastguard Worker 			test_cp_enable_with_retry(output, s, 3,
492*d83cc019SAndroid Build Coastguard Worker 						  content_type, true, false);
493*d83cc019SAndroid Build Coastguard Worker 
494*d83cc019SAndroid Build Coastguard Worker 			igt_assert_f(!igt_kmod_load("mei_hdcp", NULL),
495*d83cc019SAndroid Build Coastguard Worker 				     "mei_hdcp load failed");
496*d83cc019SAndroid Build Coastguard Worker 
497*d83cc019SAndroid Build Coastguard Worker 			/* Expected to pass */
498*d83cc019SAndroid Build Coastguard Worker 			test_cp_enable_with_retry(output, s, 3,
499*d83cc019SAndroid Build Coastguard Worker 						  content_type, false, false);
500*d83cc019SAndroid Build Coastguard Worker 		}
501*d83cc019SAndroid Build Coastguard Worker 
502*d83cc019SAndroid Build Coastguard Worker 		if (data.cp_tests & CP_LIC)
503*d83cc019SAndroid Build Coastguard Worker 			test_cp_lic(output);
504*d83cc019SAndroid Build Coastguard Worker 
505*d83cc019SAndroid Build Coastguard Worker 		if (data.cp_tests & CP_DPMS) {
506*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_set_prop_value(display, pipe,
507*d83cc019SAndroid Build Coastguard Worker 						IGT_CRTC_ACTIVE, 0);
508*d83cc019SAndroid Build Coastguard Worker 			igt_display_commit2(display, s);
509*d83cc019SAndroid Build Coastguard Worker 
510*d83cc019SAndroid Build Coastguard Worker 			igt_pipe_set_prop_value(display, pipe,
511*d83cc019SAndroid Build Coastguard Worker 						IGT_CRTC_ACTIVE, 1);
512*d83cc019SAndroid Build Coastguard Worker 			igt_display_commit2(display, s);
513*d83cc019SAndroid Build Coastguard Worker 
514*d83cc019SAndroid Build Coastguard Worker 			ret = wait_for_prop_value(output, CP_ENABLED,
515*d83cc019SAndroid Build Coastguard Worker 						  KERNEL_AUTH_TIME_ALLOWED_MSEC);
516*d83cc019SAndroid Build Coastguard Worker 			if (!ret)
517*d83cc019SAndroid Build Coastguard Worker 				test_cp_enable_with_retry(output, s, 2,
518*d83cc019SAndroid Build Coastguard Worker 							  content_type, false,
519*d83cc019SAndroid Build Coastguard Worker 							  false);
520*d83cc019SAndroid Build Coastguard Worker 		}
521*d83cc019SAndroid Build Coastguard Worker 
522*d83cc019SAndroid Build Coastguard Worker 		test_cp_disable(output, s);
523*d83cc019SAndroid Build Coastguard Worker 		primary = igt_output_get_plane_type(output,
524*d83cc019SAndroid Build Coastguard Worker 						    DRM_PLANE_TYPE_PRIMARY);
525*d83cc019SAndroid Build Coastguard Worker 		igt_plane_set_fb(primary, NULL);
526*d83cc019SAndroid Build Coastguard Worker 		igt_output_set_pipe(output, PIPE_NONE);
527*d83cc019SAndroid Build Coastguard Worker 
528*d83cc019SAndroid Build Coastguard Worker 		/*
529*d83cc019SAndroid Build Coastguard Worker 		 * Testing a output with a pipe is enough for HDCP
530*d83cc019SAndroid Build Coastguard Worker 		 * testing. No ROI in testing the connector with other
531*d83cc019SAndroid Build Coastguard Worker 		 * pipes. So Break the loop on pipe.
532*d83cc019SAndroid Build Coastguard Worker 		 */
533*d83cc019SAndroid Build Coastguard Worker 		break;
534*d83cc019SAndroid Build Coastguard Worker 	}
535*d83cc019SAndroid Build Coastguard Worker }
536*d83cc019SAndroid Build Coastguard Worker 
__debugfs_read(int fd,const char * param,char * buf,int len)537*d83cc019SAndroid Build Coastguard Worker static void __debugfs_read(int fd, const char *param, char *buf, int len)
538*d83cc019SAndroid Build Coastguard Worker {
539*d83cc019SAndroid Build Coastguard Worker 	len = igt_debugfs_simple_read(fd, param, buf, len);
540*d83cc019SAndroid Build Coastguard Worker 	if (len < 0)
541*d83cc019SAndroid Build Coastguard Worker 		igt_assert_eq(len, -ENODEV);
542*d83cc019SAndroid Build Coastguard Worker }
543*d83cc019SAndroid Build Coastguard Worker 
544*d83cc019SAndroid Build Coastguard Worker #define debugfs_read(fd, p, arr) __debugfs_read(fd, p, arr, sizeof(arr))
545*d83cc019SAndroid Build Coastguard Worker 
546*d83cc019SAndroid Build Coastguard Worker #define MAX_SINK_HDCP_CAP_BUF_LEN	5000
547*d83cc019SAndroid Build Coastguard Worker 
sink_hdcp_capable(igt_output_t * output)548*d83cc019SAndroid Build Coastguard Worker static bool sink_hdcp_capable(igt_output_t *output)
549*d83cc019SAndroid Build Coastguard Worker {
550*d83cc019SAndroid Build Coastguard Worker 	char buf[MAX_SINK_HDCP_CAP_BUF_LEN];
551*d83cc019SAndroid Build Coastguard Worker 	int fd;
552*d83cc019SAndroid Build Coastguard Worker 
553*d83cc019SAndroid Build Coastguard Worker 	fd = igt_debugfs_connector_dir(data.drm_fd, output->name, O_RDONLY);
554*d83cc019SAndroid Build Coastguard Worker 	if (fd < 0)
555*d83cc019SAndroid Build Coastguard Worker 		return false;
556*d83cc019SAndroid Build Coastguard Worker 
557*d83cc019SAndroid Build Coastguard Worker 	debugfs_read(fd, "i915_hdcp_sink_capability", buf);
558*d83cc019SAndroid Build Coastguard Worker 	close(fd);
559*d83cc019SAndroid Build Coastguard Worker 
560*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Sink capability: %s\n", buf);
561*d83cc019SAndroid Build Coastguard Worker 
562*d83cc019SAndroid Build Coastguard Worker 	return strstr(buf, "HDCP1.4");
563*d83cc019SAndroid Build Coastguard Worker }
564*d83cc019SAndroid Build Coastguard Worker 
sink_hdcp2_capable(igt_output_t * output)565*d83cc019SAndroid Build Coastguard Worker static bool sink_hdcp2_capable(igt_output_t *output)
566*d83cc019SAndroid Build Coastguard Worker {
567*d83cc019SAndroid Build Coastguard Worker 	char buf[MAX_SINK_HDCP_CAP_BUF_LEN];
568*d83cc019SAndroid Build Coastguard Worker 	int fd;
569*d83cc019SAndroid Build Coastguard Worker 
570*d83cc019SAndroid Build Coastguard Worker 	fd = igt_debugfs_connector_dir(data.drm_fd, output->name, O_RDONLY);
571*d83cc019SAndroid Build Coastguard Worker 	if (fd < 0)
572*d83cc019SAndroid Build Coastguard Worker 		return false;
573*d83cc019SAndroid Build Coastguard Worker 
574*d83cc019SAndroid Build Coastguard Worker 	debugfs_read(fd, "i915_hdcp_sink_capability", buf);
575*d83cc019SAndroid Build Coastguard Worker 	close(fd);
576*d83cc019SAndroid Build Coastguard Worker 
577*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Sink capability: %s\n", buf);
578*d83cc019SAndroid Build Coastguard Worker 
579*d83cc019SAndroid Build Coastguard Worker 	return strstr(buf, "HDCP2.2");
580*d83cc019SAndroid Build Coastguard Worker }
581*d83cc019SAndroid Build Coastguard Worker 
582*d83cc019SAndroid Build Coastguard Worker static void
test_content_protection(enum igt_commit_style s,int content_type)583*d83cc019SAndroid Build Coastguard Worker test_content_protection(enum igt_commit_style s, int content_type)
584*d83cc019SAndroid Build Coastguard Worker {
585*d83cc019SAndroid Build Coastguard Worker 	igt_display_t *display = &data.display;
586*d83cc019SAndroid Build Coastguard Worker 	igt_output_t *output;
587*d83cc019SAndroid Build Coastguard Worker 	int valid_tests = 0;
588*d83cc019SAndroid Build Coastguard Worker 
589*d83cc019SAndroid Build Coastguard Worker 	if (data.cp_tests & CP_MEI_RELOAD)
590*d83cc019SAndroid Build Coastguard Worker 		igt_require_f(igt_kmod_is_loaded("mei_hdcp"),
591*d83cc019SAndroid Build Coastguard Worker 			      "mei_hdcp module is not loaded\n");
592*d83cc019SAndroid Build Coastguard Worker 
593*d83cc019SAndroid Build Coastguard Worker 	for_each_connected_output(display, output) {
594*d83cc019SAndroid Build Coastguard Worker 		if (!output->props[IGT_CONNECTOR_CONTENT_PROTECTION])
595*d83cc019SAndroid Build Coastguard Worker 			continue;
596*d83cc019SAndroid Build Coastguard Worker 
597*d83cc019SAndroid Build Coastguard Worker 		if (!output->props[IGT_CONNECTOR_HDCP_CONTENT_TYPE] &&
598*d83cc019SAndroid Build Coastguard Worker 		    content_type)
599*d83cc019SAndroid Build Coastguard Worker 			continue;
600*d83cc019SAndroid Build Coastguard Worker 
601*d83cc019SAndroid Build Coastguard Worker 		igt_info("CP Test execution on %s\n", output->name);
602*d83cc019SAndroid Build Coastguard Worker 
603*d83cc019SAndroid Build Coastguard Worker 		if (content_type && !sink_hdcp2_capable(output)) {
604*d83cc019SAndroid Build Coastguard Worker 			igt_info("\tSkip %s (Sink has no HDCP2.2 support)\n",
605*d83cc019SAndroid Build Coastguard Worker 				 output->name);
606*d83cc019SAndroid Build Coastguard Worker 			continue;
607*d83cc019SAndroid Build Coastguard Worker 		} else if (!sink_hdcp_capable(output)) {
608*d83cc019SAndroid Build Coastguard Worker 			igt_info("\tSkip %s (Sink has no HDCP support)\n",
609*d83cc019SAndroid Build Coastguard Worker 				 output->name);
610*d83cc019SAndroid Build Coastguard Worker 			continue;
611*d83cc019SAndroid Build Coastguard Worker 		}
612*d83cc019SAndroid Build Coastguard Worker 
613*d83cc019SAndroid Build Coastguard Worker 		test_content_protection_on_output(output, s, content_type);
614*d83cc019SAndroid Build Coastguard Worker 		valid_tests++;
615*d83cc019SAndroid Build Coastguard Worker 	}
616*d83cc019SAndroid Build Coastguard Worker 
617*d83cc019SAndroid Build Coastguard Worker 	igt_require_f(valid_tests, "No connector found with HDCP capability\n");
618*d83cc019SAndroid Build Coastguard Worker }
619*d83cc019SAndroid Build Coastguard Worker 
620*d83cc019SAndroid Build Coastguard Worker igt_main
621*d83cc019SAndroid Build Coastguard Worker {
622*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
623*d83cc019SAndroid Build Coastguard Worker 		igt_skip_on_simulation();
624*d83cc019SAndroid Build Coastguard Worker 
625*d83cc019SAndroid Build Coastguard Worker 		data.drm_fd = drm_open_driver(DRIVER_ANY);
626*d83cc019SAndroid Build Coastguard Worker 
627*d83cc019SAndroid Build Coastguard Worker 		igt_display_require(&data.display, data.drm_fd);
628*d83cc019SAndroid Build Coastguard Worker 	}
629*d83cc019SAndroid Build Coastguard Worker 
630*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("legacy") {
631*d83cc019SAndroid Build Coastguard Worker 		data.cp_tests = 0;
632*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_LEGACY, HDCP_CONTENT_TYPE_0);
633*d83cc019SAndroid Build Coastguard Worker 	}
634*d83cc019SAndroid Build Coastguard Worker 
635*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("atomic") {
636*d83cc019SAndroid Build Coastguard Worker 		igt_require(data.display.is_atomic);
637*d83cc019SAndroid Build Coastguard Worker 		data.cp_tests = 0;
638*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_0);
639*d83cc019SAndroid Build Coastguard Worker 	}
640*d83cc019SAndroid Build Coastguard Worker 
641*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("atomic-dpms") {
642*d83cc019SAndroid Build Coastguard Worker 		igt_require(data.display.is_atomic);
643*d83cc019SAndroid Build Coastguard Worker 		data.cp_tests = CP_DPMS;
644*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_0);
645*d83cc019SAndroid Build Coastguard Worker 	}
646*d83cc019SAndroid Build Coastguard Worker 
647*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("LIC") {
648*d83cc019SAndroid Build Coastguard Worker 		igt_require(data.display.is_atomic);
649*d83cc019SAndroid Build Coastguard Worker 		data.cp_tests = CP_LIC;
650*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_0);
651*d83cc019SAndroid Build Coastguard Worker 	}
652*d83cc019SAndroid Build Coastguard Worker 
653*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("type1") {
654*d83cc019SAndroid Build Coastguard Worker 		igt_require(data.display.is_atomic);
655*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_1);
656*d83cc019SAndroid Build Coastguard Worker 	}
657*d83cc019SAndroid Build Coastguard Worker 
658*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("mei_interface") {
659*d83cc019SAndroid Build Coastguard Worker 		igt_require(data.display.is_atomic);
660*d83cc019SAndroid Build Coastguard Worker 		data.cp_tests = CP_MEI_RELOAD;
661*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_1);
662*d83cc019SAndroid Build Coastguard Worker 	}
663*d83cc019SAndroid Build Coastguard Worker 
664*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("content_type_change") {
665*d83cc019SAndroid Build Coastguard Worker 		igt_require(data.display.is_atomic);
666*d83cc019SAndroid Build Coastguard Worker 		data.cp_tests = CP_TYPE_CHANGE;
667*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_1);
668*d83cc019SAndroid Build Coastguard Worker 	}
669*d83cc019SAndroid Build Coastguard Worker 
670*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("uevent") {
671*d83cc019SAndroid Build Coastguard Worker 		igt_require(data.display.is_atomic);
672*d83cc019SAndroid Build Coastguard Worker 		data.cp_tests = CP_UEVENT;
673*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_0);
674*d83cc019SAndroid Build Coastguard Worker 	}
675*d83cc019SAndroid Build Coastguard Worker 
676*d83cc019SAndroid Build Coastguard Worker 	/*
677*d83cc019SAndroid Build Coastguard Worker 	 *  Testing the revocation check through SRM needs a HDCP sink with
678*d83cc019SAndroid Build Coastguard Worker 	 *  programmable Ksvs or we need a uAPI from kernel to read the
679*d83cc019SAndroid Build Coastguard Worker 	 *  connected HDCP sink's Ksv. With that we would be able to add that
680*d83cc019SAndroid Build Coastguard Worker 	 *  Ksv into a SRM and send in for revocation check. Since we dont have
681*d83cc019SAndroid Build Coastguard Worker 	 *  either of these options, we test SRM writing from userspace and
682*d83cc019SAndroid Build Coastguard Worker 	 *  validation of the same at kernel. Something is better than nothing.
683*d83cc019SAndroid Build Coastguard Worker 	 */
684*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("srm") {
685*d83cc019SAndroid Build Coastguard Worker 		bool ret;
686*d83cc019SAndroid Build Coastguard Worker 
687*d83cc019SAndroid Build Coastguard Worker 		igt_require(data.display.is_atomic);
688*d83cc019SAndroid Build Coastguard Worker 		data.cp_tests = 0;
689*d83cc019SAndroid Build Coastguard Worker 		ret = write_srm_as_fw((const __u8 *)facsimile_srm,
690*d83cc019SAndroid Build Coastguard Worker 				      sizeof(facsimile_srm));
691*d83cc019SAndroid Build Coastguard Worker 		igt_assert_f(ret, "SRM update failed");
692*d83cc019SAndroid Build Coastguard Worker 		test_content_protection(COMMIT_ATOMIC, HDCP_CONTENT_TYPE_0);
693*d83cc019SAndroid Build Coastguard Worker 	}
694*d83cc019SAndroid Build Coastguard Worker 
695*d83cc019SAndroid Build Coastguard Worker 	igt_fixture
696*d83cc019SAndroid Build Coastguard Worker 		igt_display_fini(&data.display);
697*d83cc019SAndroid Build Coastguard Worker }
698