blob: a7386b4182fbf198fec3b11aa47bbc1bc87c1816 [file] [log] [blame]
Chris Wilson07d59b32011-01-20 22:10:10 +00001/*
2 * Copyright © 2011 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 * Authors:
24 * Chris Wilson <chris@chris-wilson.co.uk>
25 *
26 */
27
28#include <unistd.h>
29#include <stdlib.h>
30#include <stdint.h>
31#include <stdio.h>
32#include <string.h>
Chris Wilson07d59b32011-01-20 22:10:10 +000033#include <fcntl.h>
34#include <inttypes.h>
35#include <errno.h>
36#include <sys/stat.h>
37#include <sys/ioctl.h>
Chris Wilson07d59b32011-01-20 22:10:10 +000038#include <sys/time.h>
39#include "drm.h"
Daniel Vettere49ceb82014-03-22 21:07:37 +010040#include "ioctl_wrappers.h"
Chris Wilson07d59b32011-01-20 22:10:10 +000041#include "drmtest.h"
Daniel Vetterc03c6ce2014-03-22 21:34:29 +010042#include "intel_io.h"
Chris Wilson07d59b32011-01-20 22:10:10 +000043
Chris Wilsoncd8d3802015-03-24 09:15:12 +000044#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
45#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
46
Zhong Libafbbf12013-04-23 15:06:45 +080047#define LOCAL_I915_EXEC_VEBOX (4<<0)
Daniel Vetter51f08302012-12-05 19:29:11 +010048
Chris Wilson2659cbb2015-03-26 12:09:57 +000049const uint32_t batch[2] = {MI_BATCH_BUFFER_END};
50int device;
51
52static int sysfs_read(const char *name)
53{
54 char buf[4096];
55 struct stat st;
56 int sysfd;
57 int len;
58
59 if (fstat(device, &st))
60 return -1;
61
62 sprintf(buf, "/sys/class/drm/card%d/%s",
63 (int)(st.st_rdev & 0x7f), name);
64 sysfd = open(buf, O_RDONLY);
65 if (sysfd < 0)
66 return -1;
67
68 len = read(sysfd, buf, sizeof(buf)-1);
69 close(sysfd);
70 if (len < 0)
71 return -1;
72
73 buf[len] = '\0';
74 return atoi(buf);
75}
76
77static int sysfs_write(const char *name, int value)
78{
79 char buf[4096];
80 struct stat st;
81 int sysfd;
82 int len;
83
84 if (fstat(device, &st))
85 return -1;
86
87 sprintf(buf, "/sys/class/drm/card%d/%s",
88 (int)(st.st_rdev & 0x7f), name);
89 sysfd = open(buf, O_WRONLY);
90 if (sysfd < 0)
91 return -1;
92
93 len = sprintf(buf, "%d", value);
94 len = write(sysfd, buf, len);
95 close(sysfd);
96
97 if (len < 0)
98 return len;
99
100 return 0;
101}
102
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000103static int dcmp(const void *A, const void *B)
104{
105 double a = *(double *)A, b = *(double *)B;
106 if (a < b)
107 return -1;
108 else if (a > b)
109 return 1;
110 else
111 return 0;
112}
113
Chris Wilson07d59b32011-01-20 22:10:10 +0000114static double elapsed(const struct timeval *start,
115 const struct timeval *end,
116 int loop)
117{
118 return (1e6*(end->tv_sec - start->tv_sec) + (end->tv_usec - start->tv_usec))/loop;
119}
120
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000121static void loop(int fd, uint32_t handle, unsigned ring_id, const char *ring_name)
Chris Wilson07d59b32011-01-20 22:10:10 +0000122{
123 struct drm_i915_gem_execbuffer2 execbuf;
Daniel Vettera7a80c22012-01-10 15:50:20 +0100124 struct drm_i915_gem_exec_object2 gem_exec[1];
Chris Wilson07d59b32011-01-20 22:10:10 +0000125 int count;
Chris Wilson07d59b32011-01-20 22:10:10 +0000126
Daniel Vetter8f5387e2013-08-13 13:20:58 +0200127 gem_require_ring(fd, ring_id);
Chris Wilson2659cbb2015-03-26 12:09:57 +0000128 igt_debug("RPS frequency range [%d, %d]\n",
129 sysfs_read("gt_min_freq_mhz"),
130 sysfs_read("gt_max_freq_mhz"));
Daniel Vetter8f5387e2013-08-13 13:20:58 +0200131
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000132 memset(&gem_exec, 0, sizeof(gem_exec));
133 gem_exec[0].handle = handle;
Chris Wilson07d59b32011-01-20 22:10:10 +0000134
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000135 memset(&execbuf, 0, sizeof(execbuf));
136 execbuf.buffers_ptr = (uintptr_t)gem_exec;
137 execbuf.buffer_count = 1;
138 execbuf.flags = ring_id;
139 execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
140 execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
141 if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)) {
142 execbuf.flags = ring_id;
143 do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
144 }
145 gem_sync(fd, handle);
146
147 for (count = 1; count <= SLOW_QUICK(1<<17, 1<<4); count <<= 1) {
148 const int reps = 9;
149 double t[reps], sum;
150 int n;
151
152 for (n = 0; n < reps; n++) {
153 struct timeval start, end;
154 int loops = count;
155 gettimeofday(&start, NULL);
156 while (loops--)
157 do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
158 gem_sync(fd, handle);
159 gettimeofday(&end, NULL);
160 t[n] = elapsed(&start, &end, count);
161 }
162
163 qsort(t, reps, sizeof(double), dcmp);
164 sum = 0;
165 for (n = 2; n < reps-2; n++)
166 sum += t[n];
167 sum /= reps - 4;
168
Daniel Vettere624fa82014-05-14 00:36:04 +0200169 igt_info("Time to exec x %d: %7.3fµs (ring=%s)\n",
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000170 count, sum, ring_name);
Chris Wilson07d59b32011-01-20 22:10:10 +0000171 fflush(stdout);
172 }
Daniel Vetterd9d95782012-12-04 17:13:05 +0100173}
Daniel Vetter8f5387e2013-08-13 13:20:58 +0200174
Chris Wilson2659cbb2015-03-26 12:09:57 +0000175static void set_auto_freq(void)
176{
177 int min = sysfs_read("gt_RPn_freq_mhz");
178 int max = sysfs_read("gt_RP0_freq_mhz");
179 if (max <= min)
180 return;
181
182 igt_debug("Setting min to %dMHz, and max to %dMHz\n", min, max);
183 sysfs_write("gt_min_freq_mhz", min);
184 sysfs_write("gt_max_freq_mhz", max);
185}
186
187static void set_min_freq(void)
188{
189 int min = sysfs_read("gt_RPn_freq_mhz");
190 igt_require(min > 0);
191 igt_debug("Setting min/max to %dMHz\n", min);
192 igt_require(sysfs_write("gt_min_freq_mhz", min) == 0 &&
193 sysfs_write("gt_max_freq_mhz", min) == 0);
194}
195
196static void set_max_freq(void)
197{
198 int max = sysfs_read("gt_RP0_freq_mhz");
199 igt_require(max > 0);
200 igt_debug("Setting min/max to %dMHz\n", max);
201 igt_require(sysfs_write("gt_max_freq_mhz", max) == 0 &&
202 sysfs_write("gt_min_freq_mhz", max) == 0);
203}
Daniel Vetterb3880d32013-08-14 18:02:46 +0200204
Daniel Vetter071e9ca2013-10-31 16:23:26 +0100205igt_main
Daniel Vetterd9d95782012-12-04 17:13:05 +0100206{
Chris Wilson2659cbb2015-03-26 12:09:57 +0000207 const struct {
208 const char *suffix;
209 void (*func)(void);
210 } rps[] = {
211 { "", set_auto_freq },
212 { "-min", set_min_freq },
213 { "-max", set_max_freq },
214 { NULL, NULL },
215 }, *r;
216 int min = -1, max = -1;
217 uint32_t handle = 0;
Daniel Vetterd9d95782012-12-04 17:13:05 +0100218
Chris Wilson2659cbb2015-03-26 12:09:57 +0000219 igt_fixture {
220 device = drm_open_any();
221
222 min = sysfs_read("gt_min_freq_mhz");
223 max = sysfs_read("gt_max_freq_mhz");
224
225 handle = gem_create(device, 4096);
226 gem_write(device, handle, 0, batch, sizeof(batch));
Daniel Vetterb3880d32013-08-14 18:02:46 +0200227 }
Daniel Vetterd9d95782012-12-04 17:13:05 +0100228
Chris Wilson2659cbb2015-03-26 12:09:57 +0000229 for (r = rps; r->suffix; r++) {
230 r->func();
Daniel Vetterd9d95782012-12-04 17:13:05 +0100231
Chris Wilson2659cbb2015-03-26 12:09:57 +0000232 igt_subtest_f("render%s", r->suffix)
233 loop(device, handle, I915_EXEC_RENDER, "render");
Daniel Vetterd9d95782012-12-04 17:13:05 +0100234
Chris Wilson2659cbb2015-03-26 12:09:57 +0000235 igt_subtest_f("bsd%s", r->suffix)
236 loop(device, handle, I915_EXEC_BSD, "bsd");
Daniel Vetterd9d95782012-12-04 17:13:05 +0100237
Chris Wilson2659cbb2015-03-26 12:09:57 +0000238 igt_subtest_f("blt%s", r->suffix)
239 loop(device, handle, I915_EXEC_BLT, "blt");
240
241 igt_subtest_f("vebox%s", r->suffix)
242 loop(device, handle, LOCAL_I915_EXEC_VEBOX, "vebox");
243 }
Daniel Vetterd9d95782012-12-04 17:13:05 +0100244
Daniel Vetterb3880d32013-08-14 18:02:46 +0200245 igt_fixture {
Chris Wilson2659cbb2015-03-26 12:09:57 +0000246 gem_close(device, handle);
Chris Wilson07d59b32011-01-20 22:10:10 +0000247
Chris Wilson2659cbb2015-03-26 12:09:57 +0000248 if (min > 0)
249 sysfs_write("gt_min_freq_mhz", min);
250 if (max > 0)
251 sysfs_write("gt_max_freq_mhz", max);
252 close(device);
Daniel Vetterb3880d32013-08-14 18:02:46 +0200253 }
Chris Wilson07d59b32011-01-20 22:10:10 +0000254}