tests: roll out igt_simple_init/igt_simple_main
[platform/upstream/intel-gpu-tools.git] / tests / pm_rps.c
1 /*
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
28 #define _GNU_SOURCE
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33 #include "drmtest.h"
34
35 static bool verbose = false;
36 static int origmin, origmax;
37
38 #define restore_assert(COND) do { \
39         if (!(COND)) { \
40                 writeval(stuff[MIN].filp, origmin); \
41                 writeval(stuff[MAX].filp, origmax); \
42                 igt_assert(0); \
43         } \
44 } while (0);
45
46 static const char sysfs_base_path[] = "/sys/class/drm/card%d/gt_%s_freq_mhz";
47 enum {
48         CUR,
49         MIN,
50         MAX,
51         RP0,
52         RP1,
53         RPn
54 };
55
56 struct junk {
57         const char *name;
58         const char *mode;
59         FILE *filp;
60 } stuff[] = {
61         { "cur", "r", NULL }, { "min", "rb+", NULL }, { "max", "rb+", NULL }, { "RP0", "r", NULL }, { "RP1", "r", NULL }, { "RPn", "r", NULL }, { NULL, NULL, NULL }
62 };
63
64 static int readval(FILE *filp)
65 {
66         int val;
67         int scanned;
68
69         fflush(filp);
70         rewind(filp);
71         scanned = fscanf(filp, "%d", &val);
72         igt_assert(scanned == 1);
73
74         return val;
75 }
76
77 static int do_writeval(FILE *filp, int val, int lerrno)
78 {
79         /* Must write twice to sysfs since the first one simply calculates the size and won't return the error */
80         int ret;
81         rewind(filp);
82         ret = fprintf(filp, "%d", val);
83         rewind(filp);
84         ret = fprintf(filp, "%d", val);
85         if (ret && lerrno)
86                 igt_assert(errno = lerrno);
87         fflush(filp);
88         return ret;
89 }
90 #define writeval(filp, val) do_writeval(filp, val, 0)
91
92 #define fcur (readval(stuff[CUR].filp))
93 #define fmin (readval(stuff[MIN].filp))
94 #define fmax (readval(stuff[MAX].filp))
95 #define frp0 (readval(stuff[RP0].filp))
96 #define frp1 (readval(stuff[RP1].filp))
97 #define frpn (readval(stuff[RPn].filp))
98
99 static void setfreq(int val)
100 {
101         writeval(stuff[MIN].filp, val);
102         writeval(stuff[MAX].filp, val);
103 }
104
105 static void checkit(void)
106 {
107         restore_assert(fmin <= fmax);
108         restore_assert(fcur <= fmax);
109         restore_assert(fmin <= fcur);
110         restore_assert(frpn <= fmin);
111         restore_assert(fmax <= frp0);
112         restore_assert(frp1 <= frp0);
113         restore_assert(frpn <= frp1);
114         restore_assert(frp0 != 0);
115         restore_assert(frp1 != 0);
116 }
117
118 static void dumpit(void)
119 {
120         struct junk *junk = stuff;
121         do {
122                 printf("gt frequency %s (MHz):  %d\n", junk->name, readval(junk->filp));
123                 junk++;
124         } while(junk->name != NULL);
125
126         printf("\n");
127 }
128
129
130 igt_simple_main
131 {
132         const int device = drm_get_card();
133         struct junk *junk = stuff;
134         int fd, ret;
135
136         igt_skip_on_simulation();
137
138         /* Use drm_open_any to verify device existence */
139         fd = drm_open_any();
140         close(fd);
141
142         do {
143                 int val = -1;
144                 char *path;
145                 ret = asprintf(&path, sysfs_base_path, device, junk->name);
146                 igt_assert(ret != -1);
147                 junk->filp = fopen(path, junk->mode);
148                 igt_require(junk->filp);
149
150                 val = readval(junk->filp);
151                 igt_assert(val >= 0);
152                 junk++;
153         } while(junk->name != NULL);
154
155         origmin = fmin;
156         origmax = fmax;
157
158         if (verbose)
159                 printf("Original min = %d\nOriginal max = %d\n", origmin, origmax);
160
161         if (verbose)
162                 dumpit();
163
164         checkit();
165         setfreq(fmin);
166         if (verbose)
167                 dumpit();
168         restore_assert(fcur == fmin);
169         setfreq(fmax);
170         if (verbose)
171                 dumpit();
172         restore_assert(fcur == fmax);
173         checkit();
174
175         /* And some errors */
176         writeval(stuff[MIN].filp, frpn - 1);
177         writeval(stuff[MAX].filp, frp0 + 1000);
178         checkit();
179
180         writeval(stuff[MIN].filp, fmax + 1000);
181         writeval(stuff[MAX].filp, fmin - 1);
182         checkit();
183
184         do_writeval(stuff[MIN].filp, 0x11111110, EINVAL);
185         do_writeval(stuff[MAX].filp, 0, EINVAL);
186
187         writeval(stuff[MIN].filp, origmin);
188         writeval(stuff[MAX].filp, origmax);
189 }