2 * Copyright © 2012 Intel Corporation
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:
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
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
24 * Ben Widawsky <ben@bwidawsk.net>
25 * Jeff McGee <jeff.mcgee@intel.com>
37 static bool verbose = false;
39 static const char sysfs_base_path[] = "/sys/class/drm/card%d/gt_%s_freq_mhz";
50 static int origfreqs[NUMFREQ];
57 { "cur", "r", NULL }, { "min", "rb+", NULL }, { "max", "rb+", NULL }, { "RP0", "r", NULL }, { "RP1", "r", NULL }, { "RPn", "r", NULL }, { NULL, NULL, NULL }
60 static int readval(FILE *filp)
66 scanned = fscanf(filp, "%d", &val);
67 igt_assert(scanned == 1);
72 static void read_freqs(int *freqs)
76 for (i = 0; i < NUMFREQ; i++)
77 freqs[i] = readval(stuff[i].filp);
80 static int do_writeval(FILE *filp, int val, int lerrno)
86 ret = fprintf(filp, "%d", val);
89 /* Expecting specific error */
90 igt_assert(ret == EOF && errno == lerrno);
91 igt_assert(readval(filp) == orig);
93 /* Expecting no error */
94 igt_assert(ret != EOF);
95 igt_assert(readval(filp) == val);
100 #define writeval(filp, val) do_writeval(filp, val, 0)
101 #define writeval_inval(filp, val) do_writeval(filp, val, EINVAL)
103 static void setfreq(int val)
105 if (val > readval(stuff[MAX].filp)) {
106 writeval(stuff[MAX].filp, val);
107 writeval(stuff[MIN].filp, val);
109 writeval(stuff[MIN].filp, val);
110 writeval(stuff[MAX].filp, val);
114 static void checkit(const int *freqs)
116 igt_assert(freqs[MIN] <= freqs[MAX]);
117 igt_assert(freqs[CUR] <= freqs[MAX]);
118 igt_assert(freqs[MIN] <= freqs[CUR]);
119 igt_assert(freqs[RPn] <= freqs[MIN]);
120 igt_assert(freqs[MAX] <= freqs[RP0]);
121 igt_assert(freqs[RP1] <= freqs[RP0]);
122 igt_assert(freqs[RPn] <= freqs[RP1]);
123 igt_assert(freqs[RP0] != 0);
124 igt_assert(freqs[RP1] != 0);
127 static void dumpit(const int *freqs)
131 printf("gt freq (MHz):");
132 for (i = 0; i < NUMFREQ; i++)
133 printf(" %s=%d", stuff[i].name, freqs[i]);
137 #define dump(x) if (verbose) dumpit(x)
138 #define log(...) if (verbose) printf(__VA_ARGS__)
140 static void min_max_config(void (*check)(void))
142 int fmid = (origfreqs[RPn] + origfreqs[RP0]) / 2;
144 log("\nCheck original min and max...\n");
147 log("\nSet min=RPn and max=RP0...\n");
148 writeval(stuff[MIN].filp, origfreqs[RPn]);
149 writeval(stuff[MAX].filp, origfreqs[RP0]);
152 log("\nIncrease min to midpoint...\n");
153 writeval(stuff[MIN].filp, fmid);
156 log("\nIncrease min to RP0...\n");
157 writeval(stuff[MIN].filp, origfreqs[RP0]);
160 log("\nIncrease min above RP0 (invalid)...\n");
161 writeval_inval(stuff[MIN].filp, origfreqs[RP0] + 1000);
164 log("\nDecrease max to RPn (invalid)...\n");
165 writeval_inval(stuff[MAX].filp, origfreqs[RPn]);
168 log("\nDecrease min to midpoint...\n");
169 writeval(stuff[MIN].filp, fmid);
172 log("\nDecrease min to RPn...\n");
173 writeval(stuff[MIN].filp, origfreqs[RPn]);
176 log("\nDecrease min below RPn (invalid)...\n");
177 writeval_inval(stuff[MIN].filp, 0);
180 log("\nDecrease max to midpoint...\n");
181 writeval(stuff[MAX].filp, fmid);
184 log("\nDecrease max to RPn...\n");
185 writeval(stuff[MAX].filp, origfreqs[RPn]);
188 log("\nDecrease max below RPn (invalid)...\n");
189 writeval_inval(stuff[MAX].filp, 0);
192 log("\nIncrease min to RP0 (invalid)...\n");
193 writeval_inval(stuff[MIN].filp, origfreqs[RP0]);
196 log("\nIncrease max to midpoint...\n");
197 writeval(stuff[MAX].filp, fmid);
200 log("\nIncrease max to RP0...\n");
201 writeval(stuff[MAX].filp, origfreqs[RP0]);
204 log("\nIncrease max above RP0 (invalid)...\n");
205 writeval_inval(stuff[MAX].filp, origfreqs[RP0] + 1000);
209 static void idle_check(void)
218 static void pm_rps_exit_handler(int sig)
220 if (origfreqs[MIN] > readval(stuff[MAX].filp)) {
221 writeval(stuff[MAX].filp, origfreqs[MAX]);
222 writeval(stuff[MIN].filp, origfreqs[MIN]);
224 writeval(stuff[MIN].filp, origfreqs[MIN]);
225 writeval(stuff[MAX].filp, origfreqs[MAX]);
229 static int opt_handler(int opt, int opt_index)
242 /* Mod of igt_subtest_init that adds our extra options */
243 static void subtest_init(int argc, char **argv)
245 struct option long_opts[] = {
246 {"verbose", 0, 0, 'v'}
248 const char *help_str = " -v, --verbose";
251 ret = igt_subtest_init_parse_opts(argc, argv, "v", long_opts,
252 help_str, opt_handler);
255 /* exit with no error for -h/--help */
256 exit(ret == -1 ? 0 : ret);
259 int main(int argc, char **argv)
261 subtest_init(argc, argv);
263 igt_skip_on_simulation();
266 const int device = drm_get_card();
267 struct junk *junk = stuff;
270 /* Use drm_open_any to verify device existence */
277 ret = asprintf(&path, sysfs_base_path, device, junk->name);
278 igt_assert(ret != -1);
279 junk->filp = fopen(path, junk->mode);
280 igt_require(junk->filp);
281 setbuf(junk->filp, NULL);
283 val = readval(junk->filp);
284 igt_assert(val >= 0);
286 } while(junk->name != NULL);
288 read_freqs(origfreqs);
290 igt_install_exit_handler(pm_rps_exit_handler);
293 igt_subtest("basic-api")
294 min_max_config(idle_check);