• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2014 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  *
23  */
24 
25 #include "igt.h"
26 
27 IGT_TEST_DESCRIPTION("Check the debugfs force connector/edid features work"
28 		     " correctly.");
29 
30 #define CHECK_MODE(m, h, w, r) \
31 	igt_assert_eq(m.hdisplay, h); igt_assert_eq(m.vdisplay, w); \
32 	igt_assert_eq(m.vrefresh, r);
33 
reset_connectors(void)34 static void reset_connectors(void)
35 {
36 	int drm_fd = 0;
37 	drmModeRes *res;
38 	drmModeConnector *connector = NULL;
39 
40 	drm_fd = drm_open_driver_master(DRIVER_INTEL);
41 	res = drmModeGetResources(drm_fd);
42 
43 	for (int i = 0; i < res->count_connectors; i++) {
44 
45 		connector = drmModeGetConnectorCurrent(drm_fd,
46 						       res->connectors[i]);
47 
48 		kmstest_force_connector(drm_fd, connector,
49 					FORCE_CONNECTOR_UNSPECIFIED);
50 
51 		kmstest_force_edid(drm_fd, connector, NULL);
52 
53 		drmModeFreeConnector(connector);
54 	}
55 
56 	igt_set_module_param_int("load_detect_test", 0);
57 }
58 
opt_handler(int opt,int opt_index,void * data)59 static int opt_handler(int opt, int opt_index, void *data)
60 {
61 	switch (opt) {
62 	case 'r':
63 		reset_connectors();
64 		exit(0);
65 		break;
66 	}
67 
68 	return IGT_OPT_HANDLER_SUCCESS;
69 }
70 
71 struct option long_opts[] = {
72 	{"reset", 0, 0, 'r'},
73 	{0, 0, 0, 0}
74 };
75 const char *help_str =
76 	"  --reset\t\tReset all connector force states and edid.\n";
77 
78 igt_main_args("", long_opts, help_str, opt_handler, NULL)
79 {
80 	/* force the VGA output and test that it worked */
81 	int drm_fd = 0;
82 	drmModeRes *res;
83 	drmModeConnector *vga_connector = NULL, *temp;
84 	int start_n_modes, start_connection;
85 
86 	igt_fixture {
87 		unsigned vga_connector_id = 0;
88 
89 		drm_fd = drm_open_driver_master(DRIVER_INTEL);
90 
91 		res = drmModeGetResources(drm_fd);
92 		igt_require(res);
93 
94 		/* find the vga connector */
95 		for (int i = 0; i < res->count_connectors; i++) {
96 			vga_connector = drmModeGetConnectorCurrent(drm_fd,
97 								   res->connectors[i]);
98 
99 			if (vga_connector->connector_type == DRM_MODE_CONNECTOR_VGA) {
100 				/* Ensure that no override was left in place. */
101 				kmstest_force_connector(drm_fd,
102 							vga_connector,
103 							FORCE_CONNECTOR_UNSPECIFIED);
104 
105 				/* Only use the first VGA connector. */
106 				if (!vga_connector_id)
107 					vga_connector_id = res->connectors[i];
108 			}
109 
110 			drmModeFreeConnector(vga_connector);
111 		}
112 
113 		igt_require(vga_connector_id);
114 
115 		/* Reacquire status after clearing any previous overrides */
116 		vga_connector = drmModeGetConnector(drm_fd, vga_connector_id);
117 
118 		start_n_modes = vga_connector->count_modes;
119 		start_connection = vga_connector->connection;
120 	}
121 
122 	igt_subtest("force-load-detect") {
123 		int i, j, w = 64, h = 64;
124 		drmModePlaneRes *plane_resources;
125 		struct igt_fb xrgb_fb, argb_fb;
126 
127 		igt_create_fb(drm_fd, w, h, DRM_FORMAT_XRGB8888, 0, &xrgb_fb);
128 		igt_create_fb(drm_fd, w, h, DRM_FORMAT_ARGB8888, 0, &argb_fb);
129 		igt_assert(drmSetClientCap(drm_fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) == 0);
130 
131 		/*
132 		 * disable all outputs to make sure we have a
133 		 * free crtc available for load detect
134 		 */
135 		kmstest_set_vt_graphics_mode();
136 		kmstest_unset_all_crtcs(drm_fd, res);
137 
138 		igt_set_module_param_int("load_detect_test", 1);
139 
140 		plane_resources = drmModeGetPlaneResources(drm_fd);
141 		igt_assert(plane_resources);
142 
143 		for (i = 0; i < plane_resources->count_planes; i++) {
144 			drmModePlane *drm_plane;
145 			bool found = false;
146 			uint32_t plane_id = plane_resources->planes[i];
147 
148 			drm_plane = drmModeGetPlane(drm_fd, plane_id);
149 			igt_assert(drm_plane);
150 
151 			for (j = 0; j < drm_plane->count_formats; j++) {
152 				uint32_t format = drm_plane->formats[j];
153 				uint32_t crtc = ffs(drm_plane->possible_crtcs) - 1;
154 				uint32_t crtc_id = res->crtcs[crtc];
155 
156 				if (format == DRM_FORMAT_XRGB8888)
157 					do_or_die(drmModeSetPlane(drm_fd, plane_id, crtc_id,
158 							xrgb_fb.fb_id,
159 							0, 0, 0, w, h,
160 							0, 0, IGT_FIXED(w, 0), IGT_FIXED(h, 0)));
161 				else if (format == DRM_FORMAT_ARGB8888)
162 					do_or_die(drmModeSetPlane(drm_fd, plane_id, crtc_id,
163 							argb_fb.fb_id,
164 							0, 0, 0, w, h,
165 							0, 0, IGT_FIXED(w, 0), IGT_FIXED(h, 0)));
166 				else
167 					continue;
168 
169 				found = true;
170 				break;
171 			}
172 			drmModeFreePlane(drm_plane);
173 			igt_assert(found);
174 		}
175 
176 		/* This can't use drmModeGetConnectorCurrent
177 		 * because connector probing is the point of this test.
178 		 */
179 		temp = drmModeGetConnector(drm_fd, vga_connector->connector_id);
180 
181 		igt_set_module_param_int("load_detect_test", 0);
182 
183 		igt_assert(temp->connection != DRM_MODE_UNKNOWNCONNECTION);
184 
185 		drmModeFreeConnector(temp);
186 
187 		/* Look if planes are unmodified. */
188 		for (i = 0; i < plane_resources->count_planes; i++) {
189 			drmModePlane *drm_plane;
190 
191 			drm_plane = drmModeGetPlane(drm_fd,
192 						    plane_resources->planes[i]);
193 			igt_assert(drm_plane);
194 
195 			igt_assert(drm_plane->crtc_id);
196 			igt_assert(drm_plane->fb_id);
197 
198 			if (drm_plane->fb_id != xrgb_fb.fb_id)
199 				igt_assert_eq(drm_plane->fb_id, argb_fb.fb_id);
200 
201 			drmModeFreePlane(drm_plane);
202 		}
203 	}
204 
205 	igt_subtest("force-connector-state") {
206 		igt_display_t display;
207 
208 		/* force the connector on and check the reported values */
209 		kmstest_force_connector(drm_fd, vga_connector, FORCE_CONNECTOR_ON);
210 		temp = drmModeGetConnectorCurrent(drm_fd,
211 						  vga_connector->connector_id);
212 		igt_assert_eq(temp->connection, DRM_MODE_CONNECTED);
213 		igt_assert_lt(0, temp->count_modes);
214 		drmModeFreeConnector(temp);
215 
216 		/* attempt to use the display */
217 		kmstest_set_vt_graphics_mode();
218 		igt_display_require(&display, drm_fd);
219 		igt_display_commit(&display);
220 		igt_display_fini(&display);
221 
222 
223 		/* force the connector off */
224 		kmstest_force_connector(drm_fd, vga_connector,
225 					FORCE_CONNECTOR_OFF);
226 		temp = drmModeGetConnectorCurrent(drm_fd,
227 						  vga_connector->connector_id);
228 		igt_assert_eq(temp->connection, DRM_MODE_DISCONNECTED);
229 		igt_assert_eq(0, temp->count_modes);
230 		drmModeFreeConnector(temp);
231 
232 		/* check that the previous state is restored */
233 		kmstest_force_connector(drm_fd, vga_connector,
234 					FORCE_CONNECTOR_UNSPECIFIED);
235 		temp = drmModeGetConnectorCurrent(drm_fd,
236 						  vga_connector->connector_id);
237 		igt_assert_eq(temp->connection, start_connection);
238 		drmModeFreeConnector(temp);
239 	}
240 
241 	igt_subtest("force-edid") {
242 		kmstest_force_connector(drm_fd, vga_connector,
243 					FORCE_CONNECTOR_ON);
244 		temp = drmModeGetConnectorCurrent(drm_fd,
245 						  vga_connector->connector_id);
246 		drmModeFreeConnector(temp);
247 
248 		/* test edid forcing */
249 		kmstest_force_edid(drm_fd, vga_connector,
250 				   igt_kms_get_base_edid());
251 		temp = drmModeGetConnectorCurrent(drm_fd,
252 						  vga_connector->connector_id);
253 
254 		igt_debug("num_conn %i\n", temp->count_modes);
255 
256 		CHECK_MODE(temp->modes[0], 1920, 1080, 60);
257 		/* Don't check non-preferred modes to avoid to tight coupling
258 		 * with the in-kernel EDID parser. */
259 
260 		drmModeFreeConnector(temp);
261 
262 		/* remove edid */
263 		kmstest_force_edid(drm_fd, vga_connector, NULL);
264 		kmstest_force_connector(drm_fd, vga_connector,
265 					FORCE_CONNECTOR_UNSPECIFIED);
266 		temp = drmModeGetConnectorCurrent(drm_fd,
267 						  vga_connector->connector_id);
268 		/* the connector should now have the same number of modes that
269 		 * it started with */
270 		igt_assert_eq(temp->count_modes, start_n_modes);
271 		drmModeFreeConnector(temp);
272 
273 	}
274 
275 	igt_subtest("prune-stale-modes") {
276 		int i;
277 
278 		kmstest_force_connector(drm_fd, vga_connector,
279 					FORCE_CONNECTOR_ON);
280 
281 		/* test pruning of stale modes */
282 		kmstest_force_edid(drm_fd, vga_connector,
283 				   igt_kms_get_alt_edid());
284 		temp = drmModeGetConnectorCurrent(drm_fd,
285 						  vga_connector->connector_id);
286 
287 		for (i = 0; i < temp->count_modes; i++) {
288 			if (temp->modes[i].hdisplay == 1400 &&
289 			    temp->modes[i].vdisplay == 1050)
290 				break;
291 		}
292 		igt_assert_f(i != temp->count_modes, "1400x1050 not on mode list\n");
293 
294 		drmModeFreeConnector(temp);
295 
296 		kmstest_force_edid(drm_fd, vga_connector,
297 				   igt_kms_get_base_edid());
298 		temp = drmModeGetConnectorCurrent(drm_fd,
299 						  vga_connector->connector_id);
300 
301 		for (i = 0; i < temp->count_modes; i++) {
302 			if (temp->modes[i].hdisplay == 1400 &&
303 			    temp->modes[i].vdisplay == 1050)
304 				break;
305 		}
306 		igt_assert_f(i == temp->count_modes, "1400x1050 not pruned from mode list\n");
307 
308 		drmModeFreeConnector(temp);
309 
310 		kmstest_force_edid(drm_fd, vga_connector, NULL);
311 		kmstest_force_connector(drm_fd, vga_connector,
312 					FORCE_CONNECTOR_UNSPECIFIED);
313 	}
314 
315 	igt_fixture {
316 		drmModeFreeConnector(vga_connector);
317 		close(drm_fd);
318 
319 		reset_connectors();
320 	}
321 }
322