blob: 79facc1f29cfa5c132118cce7d5c4ec4adabec9b [file] [log] [blame]
Ben Widawsky4fe78692012-07-11 17:06:01 -07001/*
2 * Copyright © 2012 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 * Ben Widawsky <ben@bwidawsk.net>
25 *
26 */
27
Thomas Wood804e11f2015-08-17 17:57:43 +010028#include "igt.h"
Ben Widawsky4fe78692012-07-11 17:06:01 -070029#include <stdio.h>
30#include <string.h>
Daniel Vetter254f19b2014-03-22 21:29:01 +010031#include <errno.h>
Michał Winiarskifdefdd42015-07-16 13:19:09 +020032#include <sys/utsname.h>
33#include <time.h>
Daniel Vetter254f19b2014-03-22 21:29:01 +010034
Ben Widawsky4fe78692012-07-11 17:06:01 -070035
Michał Winiarskifdefdd42015-07-16 13:19:09 +020036static bool is_x86_64;
37static bool has_proper_timestamp;
38
Ben Widawsky4fe78692012-07-11 17:06:01 -070039struct local_drm_i915_reg_read {
40 __u64 offset;
41 __u64 val; /* Return value */
42};
43
44#define REG_READ_IOCTL DRM_IOWR(DRM_COMMAND_BASE + 0x31, struct local_drm_i915_reg_read)
45
Michał Winiarskifdefdd42015-07-16 13:19:09 +020046#define RENDER_RING_TIMESTAMP 0x2358
47
48static int read_register(int fd, uint64_t offset, uint64_t * val)
Ben Widawsky58cfeab2012-07-18 11:47:42 -070049{
Michał Winiarskifdefdd42015-07-16 13:19:09 +020050 int ret = 0;
Imre Deakbcfc0f12012-10-10 16:04:43 +030051 struct local_drm_i915_reg_read reg_read;
Michał Winiarskifdefdd42015-07-16 13:19:09 +020052 reg_read.offset = offset;
Ben Widawsky58cfeab2012-07-18 11:47:42 -070053
Michał Winiarskifdefdd42015-07-16 13:19:09 +020054 if (drmIoctl(fd, REG_READ_IOCTL, &reg_read))
55 ret = -errno;
Ben Widawsky58cfeab2012-07-18 11:47:42 -070056
Michał Winiarskifdefdd42015-07-16 13:19:09 +020057 *val = reg_read.val;
58
59 return ret;
Ben Widawsky58cfeab2012-07-18 11:47:42 -070060}
61
Michał Winiarskifdefdd42015-07-16 13:19:09 +020062static bool check_kernel_x86_64(void)
Ben Widawsky4fe78692012-07-11 17:06:01 -070063{
Michał Winiarskifdefdd42015-07-16 13:19:09 +020064 int ret;
65 struct utsname uts;
Ben Widawsky4fe78692012-07-11 17:06:01 -070066
Michał Winiarskifdefdd42015-07-16 13:19:09 +020067 ret = uname(&uts);
Daniel Stonede7ccdd2015-10-01 14:16:48 +010068 igt_assert_eq(ret, 0);
Ben Widawsky4fe78692012-07-11 17:06:01 -070069
Michał Winiarskifdefdd42015-07-16 13:19:09 +020070 if (!strcmp(uts.machine, "x86_64"))
71 return true;
Ben Widawsky4fe78692012-07-11 17:06:01 -070072
Michał Winiarskifdefdd42015-07-16 13:19:09 +020073 return false;
74}
75
76static bool check_timestamp(int fd)
77{
78 int ret;
79 uint64_t val;
80
81 ret = read_register(fd, RENDER_RING_TIMESTAMP | 1, &val);
82
83 return ret == 0;
84}
85
86static int timer_query(int fd, uint64_t * val)
87{
88 uint64_t offset;
89 int ret;
90
91 offset = RENDER_RING_TIMESTAMP;
92 if (has_proper_timestamp)
93 offset |= 1;
94
95 ret = read_register(fd, offset, val);
96
97/*
98 * When reading the timestamp register with single 64b read, we are observing
99 * invalid values on x86_64:
100 *
101 * [f = valid counter value | X = garbage]
102 *
103 * i386: 0x0000000fffffffff
104 * x86_64: 0xffffffffXXXXXXXX
105 *
106 * In the absence of a corrected register read ioctl, attempt
107 * to fix up the return value to be vaguely useful.
108 */
109
110 if (is_x86_64 && !has_proper_timestamp)
111 *val >>= 32;
112
113 return ret;
114}
115
116static void test_timestamp_moving(int fd)
117{
118 uint64_t first_val, second_val;
119
120 igt_fail_on(timer_query(fd, &first_val) != 0);
Daniel Vetter81f16262012-08-05 21:40:56 +0200121 sleep(1);
Michał Winiarskifdefdd42015-07-16 13:19:09 +0200122 igt_fail_on(timer_query(fd, &second_val) != 0);
123 igt_assert(second_val != first_val);
124}
Ben Widawsky4fe78692012-07-11 17:06:01 -0700125
Michał Winiarskifdefdd42015-07-16 13:19:09 +0200126static void test_timestamp_monotonic(int fd)
127{
128 uint64_t first_val, second_val;
129 time_t start;
130 bool retry = true;
Daniel Vetter0b7ce4a2014-05-14 09:56:53 +0200131
Michał Winiarskifdefdd42015-07-16 13:19:09 +0200132 igt_fail_on(timer_query(fd, &first_val) != 0);
133 time(&start);
134 do {
135retry:
136 igt_fail_on(timer_query(fd, &second_val) != 0);
137 if (second_val < first_val && retry) {
138 /* We may hit timestamp overflow once */
139 retry = false;
140 first_val = second_val;
141 goto retry;
142 }
143 igt_assert(second_val >= first_val);
144 } while(difftime(time(NULL), start) < 5);
Ben Widawsky4fe78692012-07-11 17:06:01 -0700145
Michał Winiarskifdefdd42015-07-16 13:19:09 +0200146}
147
148igt_main
149{
150 uint64_t val = 0;
151 int fd = -1;
152
153 igt_fixture {
Micah Fedkec81d2932015-07-22 21:54:02 +0000154 fd = drm_open_driver(DRIVER_INTEL);
Michał Winiarskifdefdd42015-07-16 13:19:09 +0200155 is_x86_64 = check_kernel_x86_64();
156 has_proper_timestamp = check_timestamp(fd);
157 }
158
159 igt_subtest("bad-register")
160 igt_assert_eq(read_register(fd, 0x12345678, &val), -EINVAL);
161
162 igt_subtest("timestamp-moving") {
163 igt_skip_on(timer_query(fd, &val) != 0);
164 test_timestamp_moving(fd);
165 }
166
167 igt_subtest("timestamp-monotonic") {
168 igt_skip_on(timer_query(fd, &val) != 0);
169 test_timestamp_monotonic(fd);
170 }
171
172 igt_fixture {
173 close(fd);
174 }
Ben Widawsky4fe78692012-07-11 17:06:01 -0700175}