blob: a287d08a6d3779deeb7311653972621bd27ff0aa [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
Thomas Wood804e11f2015-08-17 17:57:43 +010028#include "igt.h"
Chris Wilson07d59b32011-01-20 22:10:10 +000029#include <unistd.h>
30#include <stdlib.h>
31#include <stdint.h>
32#include <stdio.h>
33#include <string.h>
Chris Wilson07d59b32011-01-20 22:10:10 +000034#include <fcntl.h>
35#include <inttypes.h>
36#include <errno.h>
37#include <sys/stat.h>
38#include <sys/ioctl.h>
Chris Wilson07d59b32011-01-20 22:10:10 +000039#include <sys/time.h>
Chris Wilsonb4307092015-07-01 13:53:07 +010040#include <time.h>
Chris Wilson07d59b32011-01-20 22:10:10 +000041#include "drm.h"
Chris Wilson07d59b32011-01-20 22:10:10 +000042
Chris Wilsoncd8d3802015-03-24 09:15:12 +000043#define LOCAL_I915_EXEC_NO_RELOC (1<<11)
44#define LOCAL_I915_EXEC_HANDLE_LUT (1<<12)
45
Zhong Libafbbf12013-04-23 15:06:45 +080046#define LOCAL_I915_EXEC_VEBOX (4<<0)
Daniel Vetter51f08302012-12-05 19:29:11 +010047
Chris Wilson2659cbb2015-03-26 12:09:57 +000048const uint32_t batch[2] = {MI_BATCH_BUFFER_END};
49int device;
50
51static int sysfs_read(const char *name)
52{
53 char buf[4096];
54 struct stat st;
55 int sysfd;
56 int len;
57
58 if (fstat(device, &st))
59 return -1;
60
61 sprintf(buf, "/sys/class/drm/card%d/%s",
62 (int)(st.st_rdev & 0x7f), name);
63 sysfd = open(buf, O_RDONLY);
64 if (sysfd < 0)
65 return -1;
66
67 len = read(sysfd, buf, sizeof(buf)-1);
68 close(sysfd);
69 if (len < 0)
70 return -1;
71
72 buf[len] = '\0';
73 return atoi(buf);
74}
75
76static int sysfs_write(const char *name, int value)
77{
78 char buf[4096];
79 struct stat st;
80 int sysfd;
81 int len;
82
83 if (fstat(device, &st))
84 return -1;
85
86 sprintf(buf, "/sys/class/drm/card%d/%s",
87 (int)(st.st_rdev & 0x7f), name);
88 sysfd = open(buf, O_WRONLY);
89 if (sysfd < 0)
90 return -1;
91
92 len = sprintf(buf, "%d", value);
93 len = write(sysfd, buf, len);
94 close(sysfd);
95
96 if (len < 0)
97 return len;
98
99 return 0;
100}
101
Chris Wilsonb4307092015-07-01 13:53:07 +0100102static uint64_t elapsed(const struct timespec *start,
103 const struct timespec *end,
104 int loop)
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000105{
Chris Wilsonb4307092015-07-01 13:53:07 +0100106 return (1000000000ULL*(end->tv_sec - start->tv_sec) + (end->tv_nsec - start->tv_nsec))/loop;
Chris Wilson07d59b32011-01-20 22:10:10 +0000107}
108
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000109static void loop(int fd, uint32_t handle, unsigned ring_id, const char *ring_name)
Chris Wilson07d59b32011-01-20 22:10:10 +0000110{
111 struct drm_i915_gem_execbuffer2 execbuf;
Daniel Vettera7a80c22012-01-10 15:50:20 +0100112 struct drm_i915_gem_exec_object2 gem_exec[1];
Chris Wilson07d59b32011-01-20 22:10:10 +0000113 int count;
Chris Wilson07d59b32011-01-20 22:10:10 +0000114
Daniel Vetter8f5387e2013-08-13 13:20:58 +0200115 gem_require_ring(fd, ring_id);
Chris Wilson2659cbb2015-03-26 12:09:57 +0000116 igt_debug("RPS frequency range [%d, %d]\n",
117 sysfs_read("gt_min_freq_mhz"),
118 sysfs_read("gt_max_freq_mhz"));
Daniel Vetter8f5387e2013-08-13 13:20:58 +0200119
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000120 memset(&gem_exec, 0, sizeof(gem_exec));
121 gem_exec[0].handle = handle;
Chris Wilson07d59b32011-01-20 22:10:10 +0000122
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000123 memset(&execbuf, 0, sizeof(execbuf));
124 execbuf.buffers_ptr = (uintptr_t)gem_exec;
125 execbuf.buffer_count = 1;
126 execbuf.flags = ring_id;
127 execbuf.flags |= LOCAL_I915_EXEC_HANDLE_LUT;
128 execbuf.flags |= LOCAL_I915_EXEC_NO_RELOC;
129 if (drmIoctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf)) {
130 execbuf.flags = ring_id;
131 do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
132 }
133 gem_sync(fd, handle);
134
135 for (count = 1; count <= SLOW_QUICK(1<<17, 1<<4); count <<= 1) {
Chris Wilsonb4307092015-07-01 13:53:07 +0100136 const int reps = 13;
137 igt_stats_t stats;
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000138 int n;
139
Chris Wilsonb4307092015-07-01 13:53:07 +0100140 igt_stats_init_with_size(&stats, reps);
141
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000142 for (n = 0; n < reps; n++) {
Chris Wilsonb4307092015-07-01 13:53:07 +0100143 struct timespec start, end;
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000144 int loops = count;
Chris Wilsonb4307092015-07-01 13:53:07 +0100145 sleep(1); /* wait for the hw to go back to sleep */
146 clock_gettime(CLOCK_MONOTONIC, &start);
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000147 while (loops--)
148 do_ioctl(fd, DRM_IOCTL_I915_GEM_EXECBUFFER2, &execbuf);
149 gem_sync(fd, handle);
Chris Wilsonb4307092015-07-01 13:53:07 +0100150 clock_gettime(CLOCK_MONOTONIC, &end);
151 igt_stats_push(&stats, elapsed(&start, &end, count));
Chris Wilsoncd8d3802015-03-24 09:15:12 +0000152 }
153
Daniel Vettere624fa82014-05-14 00:36:04 +0200154 igt_info("Time to exec x %d: %7.3fµs (ring=%s)\n",
Chris Wilsonb4307092015-07-01 13:53:07 +0100155 count, igt_stats_get_trimean(&stats)/1000, ring_name);
Chris Wilson07d59b32011-01-20 22:10:10 +0000156 fflush(stdout);
Chris Wilsonb4307092015-07-01 13:53:07 +0100157
158 igt_stats_fini(&stats);
Chris Wilson07d59b32011-01-20 22:10:10 +0000159 }
Daniel Vetterd9d95782012-12-04 17:13:05 +0100160}
Daniel Vetter8f5387e2013-08-13 13:20:58 +0200161
Chris Wilson2659cbb2015-03-26 12:09:57 +0000162static void set_auto_freq(void)
163{
164 int min = sysfs_read("gt_RPn_freq_mhz");
165 int max = sysfs_read("gt_RP0_freq_mhz");
166 if (max <= min)
167 return;
168
169 igt_debug("Setting min to %dMHz, and max to %dMHz\n", min, max);
170 sysfs_write("gt_min_freq_mhz", min);
171 sysfs_write("gt_max_freq_mhz", max);
172}
173
174static void set_min_freq(void)
175{
176 int min = sysfs_read("gt_RPn_freq_mhz");
177 igt_require(min > 0);
178 igt_debug("Setting min/max to %dMHz\n", min);
Chris Wilson614895f2015-07-01 20:51:54 +0100179 (void)sysfs_write("gt_idle_freq_mhz", min);
180 (void)sysfs_write("gt_boost_freq_mhz", min);
Chris Wilson2659cbb2015-03-26 12:09:57 +0000181 igt_require(sysfs_write("gt_min_freq_mhz", min) == 0 &&
182 sysfs_write("gt_max_freq_mhz", min) == 0);
183}
184
185static void set_max_freq(void)
186{
187 int max = sysfs_read("gt_RP0_freq_mhz");
188 igt_require(max > 0);
189 igt_debug("Setting min/max to %dMHz\n", max);
Chris Wilson614895f2015-07-01 20:51:54 +0100190 (void)sysfs_write("gt_idle_freq_mhz", max);
191 (void)sysfs_write("gt_boost_freq_mhz", max);
Chris Wilson2659cbb2015-03-26 12:09:57 +0000192 igt_require(sysfs_write("gt_max_freq_mhz", max) == 0 &&
193 sysfs_write("gt_min_freq_mhz", max) == 0);
194}
Daniel Vetterb3880d32013-08-14 18:02:46 +0200195
Daniel Vetter071e9ca2013-10-31 16:23:26 +0100196igt_main
Daniel Vetterd9d95782012-12-04 17:13:05 +0100197{
Chris Wilson2659cbb2015-03-26 12:09:57 +0000198 const struct {
199 const char *suffix;
200 void (*func)(void);
201 } rps[] = {
202 { "", set_auto_freq },
203 { "-min", set_min_freq },
204 { "-max", set_max_freq },
205 { NULL, NULL },
206 }, *r;
Chris Wilson614895f2015-07-01 20:51:54 +0100207 int min = -1, max = -1, boost = -1, idle = -1;
Chris Wilson2659cbb2015-03-26 12:09:57 +0000208 uint32_t handle = 0;
Daniel Vetterd9d95782012-12-04 17:13:05 +0100209
Chris Wilson2659cbb2015-03-26 12:09:57 +0000210 igt_fixture {
Micah Fedkec81d2932015-07-22 21:54:02 +0000211 device = drm_open_driver(DRIVER_INTEL);
Chris Wilson2659cbb2015-03-26 12:09:57 +0000212
213 min = sysfs_read("gt_min_freq_mhz");
214 max = sysfs_read("gt_max_freq_mhz");
Chris Wilson614895f2015-07-01 20:51:54 +0100215 boost = sysfs_read("gt_boost_freq_mhz");
216 idle = sysfs_read("gt_idle_freq_mhz");
Chris Wilson2659cbb2015-03-26 12:09:57 +0000217
218 handle = gem_create(device, 4096);
219 gem_write(device, handle, 0, batch, sizeof(batch));
Daniel Vetterb3880d32013-08-14 18:02:46 +0200220 }
Daniel Vetterd9d95782012-12-04 17:13:05 +0100221
Chris Wilson2659cbb2015-03-26 12:09:57 +0000222 for (r = rps; r->suffix; r++) {
Chris Wilson11291fd2015-03-26 20:52:00 +0000223 igt_fixture r->func();
Daniel Vetterd9d95782012-12-04 17:13:05 +0100224
Chris Wilson2659cbb2015-03-26 12:09:57 +0000225 igt_subtest_f("render%s", r->suffix)
226 loop(device, handle, I915_EXEC_RENDER, "render");
Daniel Vetterd9d95782012-12-04 17:13:05 +0100227
Chris Wilson2659cbb2015-03-26 12:09:57 +0000228 igt_subtest_f("bsd%s", r->suffix)
229 loop(device, handle, I915_EXEC_BSD, "bsd");
Daniel Vetterd9d95782012-12-04 17:13:05 +0100230
Chris Wilson2659cbb2015-03-26 12:09:57 +0000231 igt_subtest_f("blt%s", r->suffix)
232 loop(device, handle, I915_EXEC_BLT, "blt");
233
234 igt_subtest_f("vebox%s", r->suffix)
235 loop(device, handle, LOCAL_I915_EXEC_VEBOX, "vebox");
236 }
Daniel Vetterd9d95782012-12-04 17:13:05 +0100237
Daniel Vetterb3880d32013-08-14 18:02:46 +0200238 igt_fixture {
Chris Wilson2659cbb2015-03-26 12:09:57 +0000239 gem_close(device, handle);
Chris Wilson07d59b32011-01-20 22:10:10 +0000240
Chris Wilson2659cbb2015-03-26 12:09:57 +0000241 if (min > 0)
242 sysfs_write("gt_min_freq_mhz", min);
243 if (max > 0)
244 sysfs_write("gt_max_freq_mhz", max);
Chris Wilson614895f2015-07-01 20:51:54 +0100245 if (boost > 0)
246 sysfs_write("gt_boost_freq_mhz", boost);
247 if (idle > 0)
248 sysfs_write("gt_idle_freq_mhz", idle);
Chris Wilson2659cbb2015-03-26 12:09:57 +0000249 close(device);
Daniel Vetterb3880d32013-08-14 18:02:46 +0200250 }
Chris Wilson07d59b32011-01-20 22:10:10 +0000251}