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