blob: 01e874b77d651fde7d98c993ed2819d997f99376 [file] [log] [blame]
Eric Anholt8c641832009-03-26 17:15:11 -07001/*
Damien Lespiaubb33d082013-02-13 16:29:01 +00002 * Copyright © 2007, 2011, 2013 Intel Corporation
Eric Anholt8c641832009-03-26 17:15:11 -07003 *
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 * Authors:
24 * Eric Anholt <eric@anholt.net>
Daniel Vetteraa67b222012-01-10 14:59:58 +010025 * Daniel Vetter <daniel.vetter@ffwll.ch>
Eric Anholt8c641832009-03-26 17:15:11 -070026 *
27 */
28
Oscar Mateo235ff9c2013-11-12 11:50:43 +000029#ifndef ANDROID
Ben Widawsky2585bea2012-03-25 16:04:07 -070030#define _GNU_SOURCE
Oscar Mateo235ff9c2013-11-12 11:50:43 +000031#else
32#include <libgen.h>
33#endif
Ben Widawsky2585bea2012-03-25 16:04:07 -070034#include <stdio.h>
Eric Anholt8c641832009-03-26 17:15:11 -070035#include <fcntl.h>
36#include <sys/stat.h>
37#include <sys/ioctl.h>
Daniel Vetteraa67b222012-01-10 14:59:58 +010038#include <string.h>
Daniel Vetter527cad12012-01-10 18:41:46 +010039#include <sys/mman.h>
Daniel Vettercbaa8a32012-01-11 15:33:00 +010040#include <signal.h>
Daniel Vetter7b14b092012-01-15 17:40:41 +010041#include <pciaccess.h>
Damien Lespiaubb33d082013-02-13 16:29:01 +000042#include <stdlib.h>
Damien Lespiau4b347652013-04-29 16:04:52 +010043#include <unistd.h>
Daniel Vetter7553ad62013-08-12 10:43:59 +020044#include <sys/wait.h>
Tvrtko Ursulin139c72f2013-12-03 16:44:55 +000045#include <sys/types.h>
46#include <sys/syscall.h>
Daniel Vetterf1c4ec92013-12-10 09:26:08 +010047#include <sys/utsname.h>
Damien Lespiau377f48a2014-02-06 21:06:07 +000048#include <termios.h>
Daniel Vetter662d7322012-05-22 14:37:19 +020049
Eric Anholt8c641832009-03-26 17:15:11 -070050#include "drmtest.h"
Chris Wilson3c5c8ba2011-02-01 13:35:36 +000051#include "i915_drm.h"
52#include "intel_chipset.h"
Daniel Vetterc03c6ce2014-03-22 21:34:29 +010053#include "intel_io.h"
Daniel Vetter3cd45de2015-02-10 17:46:43 +010054#include "igt_gt.h"
Oscar Mateoaa252d02013-11-05 14:15:19 +000055#include "igt_debugfs.h"
Rodrigo Vivi82ad15f2014-06-09 11:15:47 -070056#include "version.h"
Ben Widawsky8c33e9a2013-12-06 20:35:29 -080057#include "config.h"
Daniel Vetter6cfcd712014-03-22 20:07:35 +010058#include "intel_reg.h"
Daniel Vettere49ceb82014-03-22 21:07:37 +010059#include "ioctl_wrappers.h"
Chris Wilson3c5c8ba2011-02-01 13:35:36 +000060
Daniel Vetter187b66d2014-03-23 15:03:14 +010061/**
62 * SECTION:drmtest
63 * @short_description: Base library for drm tests and tools
64 * @title: drmtest
Thomas Woodf0381d12015-09-07 09:26:01 +010065 * @include: igt.h
Daniel Vetter187b66d2014-03-23 15:03:14 +010066 *
67 * This library contains the basic support for writing tests, with the most
68 * important part being the helper function to open drm device nodes.
69 *
70 * But there's also a bit of other assorted stuff here.
71 *
72 * Note that this library's header pulls in the [i-g-t core](intel-gpu-tools-i-g-t-core.html)
Daniel Vetterc6c2b2b2014-03-26 15:15:49 +010073 * and [batchbuffer](intel-gpu-tools-intel-batchbuffer.html) libraries as dependencies.
Daniel Vetter187b66d2014-03-23 15:03:14 +010074 */
Daniel Vetteraa67b222012-01-10 14:59:58 +010075
Chris Wilsoneaa7e612015-02-18 15:58:06 +000076uint16_t __drm_device_id;
77
Micah Fedkee2241802015-07-22 21:42:51 +000078static int __get_drm_device_name(int fd, char *name)
Chris Wilsona6e6c5b2014-07-25 17:34:06 +010079{
80 drm_version_t version;
Chris Wilsona6e6c5b2014-07-25 17:34:06 +010081
82 memset(&version, 0, sizeof(version));
83 version.name_len = 4;
84 version.name = name;
85
Micah Fedkee2241802015-07-22 21:42:51 +000086 if (!drmIoctl(fd, DRM_IOCTL_VERSION, &version)){
Chris Wilsona6e6c5b2014-07-25 17:34:06 +010087 return 0;
Micah Fedkee2241802015-07-22 21:42:51 +000088 }
Chris Wilsona6e6c5b2014-07-25 17:34:06 +010089
Micah Fedkee2241802015-07-22 21:42:51 +000090 return -1;
Chris Wilsona6e6c5b2014-07-25 17:34:06 +010091}
92
Micah Fedkee2241802015-07-22 21:42:51 +000093static bool is_i915_device(int fd)
94{
95 int ret;
96 char name[5] = "";
97
98 ret = __get_drm_device_name(fd, name);
99
100 return !ret && strcmp("i915", name) == 0;
101}
102
Eric Anholt3f83f072016-01-22 17:18:56 -0800103static bool is_vc4_device(int fd)
104{
105 int ret;
106 char name[5] = "";
107
108 ret = __get_drm_device_name(fd, name);
109
110 return !ret && strcmp("vc4", name) == 0;
111}
112
Micah Fedkee2241802015-07-22 21:42:51 +0000113static bool is_intel(int fd)
Chris Wilson3c5c8ba2011-02-01 13:35:36 +0000114{
115 struct drm_i915_getparam gp;
Chris Wilsonacca7242014-07-21 07:57:25 +0100116 int devid = 0;
Chris Wilson3c5c8ba2011-02-01 13:35:36 +0000117
Chris Wilsonacca7242014-07-21 07:57:25 +0100118 memset(&gp, 0, sizeof(gp));
Chris Wilson3c5c8ba2011-02-01 13:35:36 +0000119 gp.param = I915_PARAM_CHIPSET_ID;
120 gp.value = &devid;
121
122 if (ioctl(fd, DRM_IOCTL_I915_GETPARAM, &gp, sizeof(gp)))
Micah Fedkee2241802015-07-22 21:42:51 +0000123 return false;
Chris Wilson3c5c8ba2011-02-01 13:35:36 +0000124
Chris Wilsoneaa7e612015-02-18 15:58:06 +0000125 if (!IS_INTEL(devid))
Micah Fedkee2241802015-07-22 21:42:51 +0000126 return false;
Chris Wilsoneaa7e612015-02-18 15:58:06 +0000127
128 __drm_device_id = devid;
Micah Fedkee2241802015-07-22 21:42:51 +0000129 return true;
Chris Wilson3c5c8ba2011-02-01 13:35:36 +0000130}
Eric Anholt8c641832009-03-26 17:15:11 -0700131
Imre Deaka3b47db2013-05-28 17:22:57 +0300132#define LOCAL_I915_EXEC_VEBOX (4 << 0)
Daniel Vetter187b66d2014-03-23 15:03:14 +0100133/**
134 * gem_quiescent_gpu:
135 * @fd: open i915 drm file descriptor
136 *
137 * Ensure the gpu is idle by launching a nop execbuf and stalling for it. This
138 * is automatically run when opening a drm device node and is also installed as
139 * an exit handler to have the best assurance that the test is run in a pristine
140 * and controlled environment.
141 *
142 * This function simply allows tests to make additional calls in-between, if so
143 * desired.
144 */
Daniel Vetter9f876602012-01-11 17:19:53 +0100145void gem_quiescent_gpu(int fd)
146{
Chris Wilson0501dcf2016-03-04 15:35:24 +0000147 uint32_t bbe = MI_BATCH_BUFFER_END;
Daniel Vetter9f876602012-01-11 17:19:53 +0100148 struct drm_i915_gem_execbuffer2 execbuf;
Chris Wilson0501dcf2016-03-04 15:35:24 +0000149 struct drm_i915_gem_exec_object2 obj;
150 unsigned ring;
Daniel Vetter9f876602012-01-11 17:19:53 +0100151
Chris Wilson0501dcf2016-03-04 15:35:24 +0000152 memset(&obj, 0, sizeof(obj));
153 obj.handle = gem_create(fd, 4096);
154 gem_write(fd, obj.handle, 0, &bbe, sizeof(&bbe));
Daniel Vetter9f876602012-01-11 17:19:53 +0100155
Chris Wilson59f076a2015-11-20 11:23:37 +0000156 memset(&execbuf, 0, sizeof(execbuf));
Chris Wilson0501dcf2016-03-04 15:35:24 +0000157 execbuf.buffers_ptr = (uintptr_t)&obj;
Daniel Vetter9f876602012-01-11 17:19:53 +0100158 execbuf.buffer_count = 1;
Daniel Vetter9f876602012-01-11 17:19:53 +0100159
Chris Wilson0501dcf2016-03-04 15:35:24 +0000160 for (ring = 0; ring < 1<<6; ring++) {
161 execbuf.flags = ring;
162 __gem_execbuf(fd, &execbuf);
Imre Deaka3b47db2013-05-28 17:22:57 +0300163 }
164
Chris Wilson310f99c2016-03-04 15:03:42 +0000165 if (gem_has_bsd2(fd)) {
166 execbuf.flags = I915_EXEC_BSD | (2 << 13);
Chris Wilson0501dcf2016-03-04 15:35:24 +0000167 __gem_execbuf(fd, &execbuf);
Chris Wilson310f99c2016-03-04 15:03:42 +0000168 }
169
Chris Wilson0501dcf2016-03-04 15:35:24 +0000170 gem_sync(fd, obj.handle);
171 gem_close(fd, obj.handle);
Imre Deaka3b47db2013-05-28 17:22:57 +0300172
Oscar Mateoaa252d02013-11-05 14:15:19 +0000173 igt_drop_caches_set(DROP_RETIRE);
Daniel Vetter9f876602012-01-11 17:19:53 +0100174}
175
Ben Widawsky2585bea2012-03-25 16:04:07 -0700176/**
Thomas Wood2d443862014-03-11 16:04:29 +0000177 * drm_get_card:
Ben Widawsky2585bea2012-03-25 16:04:07 -0700178 *
Daniel Vetter187b66d2014-03-23 15:03:14 +0100179 * Get an i915 drm card index number for use in /dev or /sys. The minor index of
180 * the legacy node is returned, not of the control or render node.
Thomas Wood2d443862014-03-11 16:04:29 +0000181 *
Daniel Vetter187b66d2014-03-23 15:03:14 +0100182 * Returns:
183 * The i915 drm index or -1 on error
Ben Widawsky2585bea2012-03-25 16:04:07 -0700184 */
Daniel Vetter5951ffb2013-08-19 10:34:34 +0200185int drm_get_card(void)
Ben Widawsky2585bea2012-03-25 16:04:07 -0700186{
187 char *name;
Eric Anholt8c641832009-03-26 17:15:11 -0700188 int i, fd;
189
190 for (i = 0; i < 16; i++) {
Ben Widawsky2585bea2012-03-25 16:04:07 -0700191 int ret;
192
193 ret = asprintf(&name, "/dev/dri/card%u", i);
Daniel Vetter8dbd1fb2013-08-19 11:09:25 +0200194 igt_assert(ret != -1);
195
Eric Anholt8c641832009-03-26 17:15:11 -0700196 fd = open(name, O_RDWR);
Ben Widawsky2585bea2012-03-25 16:04:07 -0700197 free(name);
198
Chris Wilson3c5c8ba2011-02-01 13:35:36 +0000199 if (fd == -1)
200 continue;
201
Chris Wilsona6e6c5b2014-07-25 17:34:06 +0100202 if (!is_i915_device(fd) || !is_intel(fd)) {
Damien Lespiau8329acb2013-10-24 15:04:26 +0100203 close(fd);
Daniel Vetter8dbd1fb2013-08-19 11:09:25 +0200204 continue;
Damien Lespiau8329acb2013-10-24 15:04:26 +0100205 }
Chris Wilson3c5c8ba2011-02-01 13:35:36 +0000206
207 close(fd);
Daniel Vetter8dbd1fb2013-08-19 11:09:25 +0200208 return i;
Eric Anholt8c641832009-03-26 17:15:11 -0700209 }
Ben Widawsky2585bea2012-03-25 16:04:07 -0700210
Daniel Vetter8dbd1fb2013-08-19 11:09:25 +0200211 igt_skip("No intel gpu found\n");
212
213 return -1;
Eric Anholt8c641832009-03-26 17:15:11 -0700214}
215
Micah Fedkee2241802015-07-22 21:42:51 +0000216/**
217 * __drm_open_driver:
Thomas Wood683316c2015-11-30 16:36:16 +0000218 * @chipset: OR'd flags for each chipset to search, eg. #DRIVER_INTEL
Micah Fedkee2241802015-07-22 21:42:51 +0000219 *
220 * Open the first DRM device we can find, searching up to 16 device nodes
221 *
Micah Fedkee2241802015-07-22 21:42:51 +0000222 * Returns:
223 * An open DRM fd or -1 on error
224 */
225int __drm_open_driver(int chipset)
Ben Widawsky2585bea2012-03-25 16:04:07 -0700226{
Chris Wilsona6e6c5b2014-07-25 17:34:06 +0100227 for (int i = 0; i < 16; i++) {
228 char name[80];
229 int fd;
Eric Anholt3f83f072016-01-22 17:18:56 -0800230 bool found_intel, found_vc4;
Ben Widawsky2585bea2012-03-25 16:04:07 -0700231
Chris Wilsona6e6c5b2014-07-25 17:34:06 +0100232 sprintf(name, "/dev/dri/card%u", i);
233 fd = open(name, O_RDWR);
234 if (fd == -1)
235 continue;
Ben Widawsky2585bea2012-03-25 16:04:07 -0700236
Micah Fedkee2241802015-07-22 21:42:51 +0000237 found_intel = is_i915_device(fd) && is_intel(fd) && (chipset & DRIVER_INTEL);
238
Eric Anholt3f83f072016-01-22 17:18:56 -0800239 found_vc4 = is_vc4_device(fd) && (chipset & DRIVER_VC4);
240
241 if ((chipset & DRIVER_ANY) || found_intel || found_vc4)
Chris Wilsona6e6c5b2014-07-25 17:34:06 +0100242 return fd;
Ben Widawsky2585bea2012-03-25 16:04:07 -0700243
Chris Wilson9eb7d892013-07-03 09:58:28 +0100244 close(fd);
Chris Wilson9eb7d892013-07-03 09:58:28 +0100245 }
Ben Widawsky2585bea2012-03-25 16:04:07 -0700246
Chris Wilsona6e6c5b2014-07-25 17:34:06 +0100247 igt_skip("No intel gpu found\n");
248 return -1;
Ben Widawsky2585bea2012-03-25 16:04:07 -0700249}
Eric Anholt8c641832009-03-26 17:15:11 -0700250
Micah Fedkee2241802015-07-22 21:42:51 +0000251static int __drm_open_driver_render(int chipset)
Damien Lespiau69c200b2013-10-24 15:19:32 +0100252{
253 char *name;
254 int i, fd;
255
256 for (i = 128; i < (128 + 16); i++) {
257 int ret;
258
259 ret = asprintf(&name, "/dev/dri/renderD%u", i);
260 igt_assert(ret != -1);
261
262 fd = open(name, O_RDWR);
263 free(name);
264
265 if (fd == -1)
266 continue;
267
Chris Wilsona6e6c5b2014-07-25 17:34:06 +0100268 if (!is_i915_device(fd) || !is_intel(fd)) {
Damien Lespiau69c200b2013-10-24 15:19:32 +0100269 close(fd);
270 fd = -1;
271 continue;
272 }
273
274 return fd;
275 }
276
277 return fd;
278}
279
Imre Deak2423b6c2014-02-05 13:48:26 +0200280static int at_exit_drm_fd = -1;
281static int at_exit_drm_render_fd = -1;
282
Imre Deak1cb4f902013-05-28 17:35:32 +0300283static void quiescent_gpu_at_exit(int sig)
284{
Imre Deak2423b6c2014-02-05 13:48:26 +0200285 if (at_exit_drm_fd < 0)
286 return;
Imre Deak1cb4f902013-05-28 17:35:32 +0300287
Imre Deak2423b6c2014-02-05 13:48:26 +0200288 gem_quiescent_gpu(at_exit_drm_fd);
289 close(at_exit_drm_fd);
290 at_exit_drm_fd = -1;
Imre Deak1cb4f902013-05-28 17:35:32 +0300291}
292
Damien Lespiau69c200b2013-10-24 15:19:32 +0100293static void quiescent_gpu_at_exit_render(int sig)
294{
Imre Deak2423b6c2014-02-05 13:48:26 +0200295 if (at_exit_drm_render_fd < 0)
296 return;
Damien Lespiau69c200b2013-10-24 15:19:32 +0100297
Imre Deak2423b6c2014-02-05 13:48:26 +0200298 gem_quiescent_gpu(at_exit_drm_render_fd);
299 close(at_exit_drm_render_fd);
300 at_exit_drm_render_fd = -1;
Damien Lespiau69c200b2013-10-24 15:19:32 +0100301}
302
Daniel Vetter187b66d2014-03-23 15:03:14 +0100303/**
Micah Fedkee2241802015-07-22 21:42:51 +0000304 * drm_open_driver:
Thomas Wood683316c2015-11-30 16:36:16 +0000305 * @chipset: OR'd flags for each chipset to search, eg. #DRIVER_INTEL
Daniel Vetter187b66d2014-03-23 15:03:14 +0100306 *
Micah Fedkee2241802015-07-22 21:42:51 +0000307 * Open a drm legacy device node. This function always returns a valid
Thomas Wood032f30c2015-01-13 13:33:57 +0000308 * file descriptor.
Daniel Vetter187b66d2014-03-23 15:03:14 +0100309 *
Micah Fedkee2241802015-07-22 21:42:51 +0000310 * Returns: a drm file descriptor
Daniel Vetter187b66d2014-03-23 15:03:14 +0100311 */
Micah Fedkee2241802015-07-22 21:42:51 +0000312int drm_open_driver(int chipset)
Imre Deak1cb4f902013-05-28 17:35:32 +0300313{
314 static int open_count;
Micah Fedkee2241802015-07-22 21:42:51 +0000315 int fd = __drm_open_driver(chipset);
Imre Deak1cb4f902013-05-28 17:35:32 +0300316
Daniel Vetter4ba1f2e2013-08-19 07:57:03 +0200317 igt_require(fd >= 0);
Chris Wilson9eb7d892013-07-03 09:58:28 +0100318
319 if (__sync_fetch_and_add(&open_count, 1))
Imre Deak1cb4f902013-05-28 17:35:32 +0300320 return fd;
321
Micah Fedkee2241802015-07-22 21:42:51 +0000322 if(chipset & DRIVER_INTEL){
323 gem_quiescent_gpu(fd);
324 igt_install_exit_handler(quiescent_gpu_at_exit);
325 }
326 at_exit_drm_fd = __drm_open_driver(chipset);
Imre Deak1cb4f902013-05-28 17:35:32 +0300327
328 return fd;
329}
330
Daniel Vetter187b66d2014-03-23 15:03:14 +0100331/**
Micah Fedkee2241802015-07-22 21:42:51 +0000332 * drm_open_driver_master:
Thomas Wood683316c2015-11-30 16:36:16 +0000333 * @chipset: OR'd flags for each chipset to search, eg. #DRIVER_INTEL
Imre Deakbfda78c2014-09-18 18:25:37 +0300334 *
Micah Fedkee2241802015-07-22 21:42:51 +0000335 * Open a drm legacy device node and ensure that it is drm master.
Imre Deakbfda78c2014-09-18 18:25:37 +0300336 *
337 * Returns:
Micah Fedkee2241802015-07-22 21:42:51 +0000338 * The drm file descriptor or -1 on error
Imre Deakbfda78c2014-09-18 18:25:37 +0300339 */
Micah Fedkee2241802015-07-22 21:42:51 +0000340int drm_open_driver_master(int chipset)
Imre Deakbfda78c2014-09-18 18:25:37 +0300341{
Micah Fedkee2241802015-07-22 21:42:51 +0000342 int fd = drm_open_driver(chipset);
Imre Deakbfda78c2014-09-18 18:25:37 +0300343
344 igt_require(fd >= 0);
345 igt_require_f(drmSetMaster(fd) == 0, "Can't become DRM master, "
346 "please check if no other DRM client is running.\n");
347
348 return fd;
349}
350
351/**
Micah Fedkee2241802015-07-22 21:42:51 +0000352 * drm_open_driver_render:
Thomas Wood683316c2015-11-30 16:36:16 +0000353 * @chipset: OR'd flags for each chipset to search, eg. #DRIVER_INTEL
Daniel Vetter187b66d2014-03-23 15:03:14 +0100354 *
Micah Fedkee2241802015-07-22 21:42:51 +0000355 * Open a drm render device node.
Daniel Vetter187b66d2014-03-23 15:03:14 +0100356 *
357 * Returns:
Micah Fedkee2241802015-07-22 21:42:51 +0000358 * The drm file descriptor or -1 on error
Daniel Vetter187b66d2014-03-23 15:03:14 +0100359 */
Micah Fedkee2241802015-07-22 21:42:51 +0000360int drm_open_driver_render(int chipset)
Damien Lespiau69c200b2013-10-24 15:19:32 +0100361{
362 static int open_count;
Micah Fedkee2241802015-07-22 21:42:51 +0000363 int fd = __drm_open_driver_render(chipset);
Damien Lespiau69c200b2013-10-24 15:19:32 +0100364
Micah Fedkee2241802015-07-22 21:42:51 +0000365 /* no render nodes, fallback to drm_open_driver() */
Damien Lespiau69c200b2013-10-24 15:19:32 +0100366 if (fd == -1)
Micah Fedkee2241802015-07-22 21:42:51 +0000367 return drm_open_driver(chipset);
Damien Lespiau69c200b2013-10-24 15:19:32 +0100368
369 if (__sync_fetch_and_add(&open_count, 1))
370 return fd;
371
Micah Fedkee2241802015-07-22 21:42:51 +0000372 at_exit_drm_render_fd = __drm_open_driver(chipset);
373 if(chipset & DRIVER_INTEL){
374 gem_quiescent_gpu(fd);
375 igt_install_exit_handler(quiescent_gpu_at_exit_render);
376 }
Damien Lespiau69c200b2013-10-24 15:19:32 +0100377
378 return fd;
379}