xref: /aosp_15_r20/external/igt-gpu-tools/tests/i915/i915_pm_rps.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker /*
2*d83cc019SAndroid Build Coastguard Worker  * Copyright © 2012 Intel Corporation
3*d83cc019SAndroid Build Coastguard Worker  *
4*d83cc019SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
5*d83cc019SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
6*d83cc019SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
7*d83cc019SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*d83cc019SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
9*d83cc019SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
10*d83cc019SAndroid Build Coastguard Worker  *
11*d83cc019SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
12*d83cc019SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
13*d83cc019SAndroid Build Coastguard Worker  * Software.
14*d83cc019SAndroid Build Coastguard Worker  *
15*d83cc019SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*d83cc019SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*d83cc019SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18*d83cc019SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*d83cc019SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*d83cc019SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*d83cc019SAndroid Build Coastguard Worker  * IN THE SOFTWARE.
22*d83cc019SAndroid Build Coastguard Worker  *
23*d83cc019SAndroid Build Coastguard Worker  * Authors:
24*d83cc019SAndroid Build Coastguard Worker  *    Ben Widawsky <[email protected]>
25*d83cc019SAndroid Build Coastguard Worker  *    Jeff McGee <[email protected]>
26*d83cc019SAndroid Build Coastguard Worker  *
27*d83cc019SAndroid Build Coastguard Worker  */
28*d83cc019SAndroid Build Coastguard Worker 
29*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
33*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
34*d83cc019SAndroid Build Coastguard Worker #include <signal.h>
35*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
36*d83cc019SAndroid Build Coastguard Worker #include <time.h>
37*d83cc019SAndroid Build Coastguard Worker #include <sys/wait.h>
38*d83cc019SAndroid Build Coastguard Worker 
39*d83cc019SAndroid Build Coastguard Worker #include "igt.h"
40*d83cc019SAndroid Build Coastguard Worker #include "igt_dummyload.h"
41*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
42*d83cc019SAndroid Build Coastguard Worker 
43*d83cc019SAndroid Build Coastguard Worker IGT_TEST_DESCRIPTION("Render P-States tests - verify GPU frequency changes");
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker static int drm_fd;
46*d83cc019SAndroid Build Coastguard Worker 
47*d83cc019SAndroid Build Coastguard Worker enum {
48*d83cc019SAndroid Build Coastguard Worker 	CUR,
49*d83cc019SAndroid Build Coastguard Worker 	MIN,
50*d83cc019SAndroid Build Coastguard Worker 	MAX,
51*d83cc019SAndroid Build Coastguard Worker 	RP0,
52*d83cc019SAndroid Build Coastguard Worker 	RP1,
53*d83cc019SAndroid Build Coastguard Worker 	RPn,
54*d83cc019SAndroid Build Coastguard Worker 	BOOST,
55*d83cc019SAndroid Build Coastguard Worker 	NUMFREQ
56*d83cc019SAndroid Build Coastguard Worker };
57*d83cc019SAndroid Build Coastguard Worker 
58*d83cc019SAndroid Build Coastguard Worker static int origfreqs[NUMFREQ];
59*d83cc019SAndroid Build Coastguard Worker 
60*d83cc019SAndroid Build Coastguard Worker struct sysfs_file {
61*d83cc019SAndroid Build Coastguard Worker 	const char *name;
62*d83cc019SAndroid Build Coastguard Worker 	const char *mode;
63*d83cc019SAndroid Build Coastguard Worker 	FILE *filp;
64*d83cc019SAndroid Build Coastguard Worker } sysfs_files[] = {
65*d83cc019SAndroid Build Coastguard Worker 	{ "cur", "r", NULL },
66*d83cc019SAndroid Build Coastguard Worker 	{ "min", "rb+", NULL },
67*d83cc019SAndroid Build Coastguard Worker 	{ "max", "rb+", NULL },
68*d83cc019SAndroid Build Coastguard Worker 	{ "RP0", "r", NULL },
69*d83cc019SAndroid Build Coastguard Worker 	{ "RP1", "r", NULL },
70*d83cc019SAndroid Build Coastguard Worker 	{ "RPn", "r", NULL },
71*d83cc019SAndroid Build Coastguard Worker 	{ "boost", "rb+", NULL },
72*d83cc019SAndroid Build Coastguard Worker 	{ NULL, NULL, NULL }
73*d83cc019SAndroid Build Coastguard Worker };
74*d83cc019SAndroid Build Coastguard Worker 
readval(FILE * filp)75*d83cc019SAndroid Build Coastguard Worker static int readval(FILE *filp)
76*d83cc019SAndroid Build Coastguard Worker {
77*d83cc019SAndroid Build Coastguard Worker 	int val;
78*d83cc019SAndroid Build Coastguard Worker 	int scanned;
79*d83cc019SAndroid Build Coastguard Worker 
80*d83cc019SAndroid Build Coastguard Worker 	rewind(filp);
81*d83cc019SAndroid Build Coastguard Worker 	scanned = fscanf(filp, "%d", &val);
82*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(scanned, 1);
83*d83cc019SAndroid Build Coastguard Worker 
84*d83cc019SAndroid Build Coastguard Worker 	return val;
85*d83cc019SAndroid Build Coastguard Worker }
86*d83cc019SAndroid Build Coastguard Worker 
read_freqs(int * freqs)87*d83cc019SAndroid Build Coastguard Worker static void read_freqs(int *freqs)
88*d83cc019SAndroid Build Coastguard Worker {
89*d83cc019SAndroid Build Coastguard Worker 	int i;
90*d83cc019SAndroid Build Coastguard Worker 
91*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < NUMFREQ; i++)
92*d83cc019SAndroid Build Coastguard Worker 		freqs[i] = readval(sysfs_files[i].filp);
93*d83cc019SAndroid Build Coastguard Worker }
94*d83cc019SAndroid Build Coastguard Worker 
nsleep(unsigned long ns)95*d83cc019SAndroid Build Coastguard Worker static void nsleep(unsigned long ns)
96*d83cc019SAndroid Build Coastguard Worker {
97*d83cc019SAndroid Build Coastguard Worker 	struct timespec ts;
98*d83cc019SAndroid Build Coastguard Worker 	int ret;
99*d83cc019SAndroid Build Coastguard Worker 
100*d83cc019SAndroid Build Coastguard Worker 	ts.tv_sec = 0;
101*d83cc019SAndroid Build Coastguard Worker 	ts.tv_nsec = ns;
102*d83cc019SAndroid Build Coastguard Worker 	do {
103*d83cc019SAndroid Build Coastguard Worker 		struct timespec rem;
104*d83cc019SAndroid Build Coastguard Worker 
105*d83cc019SAndroid Build Coastguard Worker 		ret = nanosleep(&ts, &rem);
106*d83cc019SAndroid Build Coastguard Worker 		igt_assert(ret == 0 || errno == EINTR);
107*d83cc019SAndroid Build Coastguard Worker 		ts = rem;
108*d83cc019SAndroid Build Coastguard Worker 	} while (ret && errno == EINTR);
109*d83cc019SAndroid Build Coastguard Worker }
110*d83cc019SAndroid Build Coastguard Worker 
wait_freq_settle(void)111*d83cc019SAndroid Build Coastguard Worker static void wait_freq_settle(void)
112*d83cc019SAndroid Build Coastguard Worker {
113*d83cc019SAndroid Build Coastguard Worker 	int timeout = 10;
114*d83cc019SAndroid Build Coastguard Worker 
115*d83cc019SAndroid Build Coastguard Worker 	while (1) {
116*d83cc019SAndroid Build Coastguard Worker 		int freqs[NUMFREQ];
117*d83cc019SAndroid Build Coastguard Worker 
118*d83cc019SAndroid Build Coastguard Worker 		read_freqs(freqs);
119*d83cc019SAndroid Build Coastguard Worker 		if (freqs[CUR] >= freqs[MIN] && freqs[CUR] <= freqs[MAX])
120*d83cc019SAndroid Build Coastguard Worker 			break;
121*d83cc019SAndroid Build Coastguard Worker 		nsleep(1000000);
122*d83cc019SAndroid Build Coastguard Worker 		if (!timeout--)
123*d83cc019SAndroid Build Coastguard Worker 			break;
124*d83cc019SAndroid Build Coastguard Worker 	}
125*d83cc019SAndroid Build Coastguard Worker }
126*d83cc019SAndroid Build Coastguard Worker 
do_writeval(FILE * filp,int val,int lerrno,bool readback_check)127*d83cc019SAndroid Build Coastguard Worker static int do_writeval(FILE *filp, int val, int lerrno, bool readback_check)
128*d83cc019SAndroid Build Coastguard Worker {
129*d83cc019SAndroid Build Coastguard Worker 	int ret, orig;
130*d83cc019SAndroid Build Coastguard Worker 
131*d83cc019SAndroid Build Coastguard Worker 	orig = readval(filp);
132*d83cc019SAndroid Build Coastguard Worker 	rewind(filp);
133*d83cc019SAndroid Build Coastguard Worker 	ret = fprintf(filp, "%d", val);
134*d83cc019SAndroid Build Coastguard Worker 
135*d83cc019SAndroid Build Coastguard Worker 	if (lerrno) {
136*d83cc019SAndroid Build Coastguard Worker 		/* Expecting specific error */
137*d83cc019SAndroid Build Coastguard Worker 		igt_assert(ret == EOF && errno == lerrno);
138*d83cc019SAndroid Build Coastguard Worker 		if (readback_check)
139*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(readval(filp), orig);
140*d83cc019SAndroid Build Coastguard Worker 	} else {
141*d83cc019SAndroid Build Coastguard Worker 		/* Expecting no error */
142*d83cc019SAndroid Build Coastguard Worker 		igt_assert_lt(0, ret);
143*d83cc019SAndroid Build Coastguard Worker 		wait_freq_settle();
144*d83cc019SAndroid Build Coastguard Worker 		if (readback_check)
145*d83cc019SAndroid Build Coastguard Worker 			igt_assert_eq(readval(filp), val);
146*d83cc019SAndroid Build Coastguard Worker 	}
147*d83cc019SAndroid Build Coastguard Worker 
148*d83cc019SAndroid Build Coastguard Worker 	return ret;
149*d83cc019SAndroid Build Coastguard Worker }
150*d83cc019SAndroid Build Coastguard Worker #define writeval(filp, val) do_writeval(filp, val, 0, true)
151*d83cc019SAndroid Build Coastguard Worker #define writeval_inval(filp, val) do_writeval(filp, val, EINVAL, true)
152*d83cc019SAndroid Build Coastguard Worker #define writeval_nocheck(filp, val) do_writeval(filp, val, 0, false)
153*d83cc019SAndroid Build Coastguard Worker 
check_freq_constraints(const int * freqs)154*d83cc019SAndroid Build Coastguard Worker static void check_freq_constraints(const int *freqs)
155*d83cc019SAndroid Build Coastguard Worker {
156*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(freqs[MIN], freqs[MAX]);
157*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(freqs[CUR], freqs[MAX]);
158*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(freqs[RPn], freqs[CUR]);
159*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(freqs[RPn], freqs[MIN]);
160*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(freqs[MAX], freqs[RP0]);
161*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(freqs[RP1], freqs[RP0]);
162*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(freqs[RPn], freqs[RP1]);
163*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(freqs[RP0], 0);
164*d83cc019SAndroid Build Coastguard Worker 	igt_assert_neq(freqs[RP1], 0);
165*d83cc019SAndroid Build Coastguard Worker }
166*d83cc019SAndroid Build Coastguard Worker 
dump(const int * freqs)167*d83cc019SAndroid Build Coastguard Worker static void dump(const int *freqs)
168*d83cc019SAndroid Build Coastguard Worker {
169*d83cc019SAndroid Build Coastguard Worker 	int i;
170*d83cc019SAndroid Build Coastguard Worker 
171*d83cc019SAndroid Build Coastguard Worker 	igt_debug("gt freq (MHz):");
172*d83cc019SAndroid Build Coastguard Worker 	for (i = 0; i < NUMFREQ; i++)
173*d83cc019SAndroid Build Coastguard Worker 		igt_debug("  %s=%d", sysfs_files[i].name, freqs[i]);
174*d83cc019SAndroid Build Coastguard Worker 
175*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\n");
176*d83cc019SAndroid Build Coastguard Worker }
177*d83cc019SAndroid Build Coastguard Worker 
178*d83cc019SAndroid Build Coastguard Worker enum load {
179*d83cc019SAndroid Build Coastguard Worker 	LOW = 0,
180*d83cc019SAndroid Build Coastguard Worker 	HIGH
181*d83cc019SAndroid Build Coastguard Worker };
182*d83cc019SAndroid Build Coastguard Worker 
183*d83cc019SAndroid Build Coastguard Worker static struct load_helper {
184*d83cc019SAndroid Build Coastguard Worker 	int link;
185*d83cc019SAndroid Build Coastguard Worker 	enum load load;
186*d83cc019SAndroid Build Coastguard Worker 	bool exit;
187*d83cc019SAndroid Build Coastguard Worker 	bool signal;
188*d83cc019SAndroid Build Coastguard Worker 	struct igt_helper_process igt_proc;
189*d83cc019SAndroid Build Coastguard Worker } lh;
190*d83cc019SAndroid Build Coastguard Worker 
load_helper_signal_handler(int sig)191*d83cc019SAndroid Build Coastguard Worker static void load_helper_signal_handler(int sig)
192*d83cc019SAndroid Build Coastguard Worker {
193*d83cc019SAndroid Build Coastguard Worker 	if (sig == SIGUSR2) {
194*d83cc019SAndroid Build Coastguard Worker 		lh.load = !lh.load;
195*d83cc019SAndroid Build Coastguard Worker 		lh.signal = true;
196*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Switching background load to %s\n", lh.load ? "high" : "low");
197*d83cc019SAndroid Build Coastguard Worker 	} else
198*d83cc019SAndroid Build Coastguard Worker 		lh.exit = true;
199*d83cc019SAndroid Build Coastguard Worker }
200*d83cc019SAndroid Build Coastguard Worker 
load_helper_sync(void)201*d83cc019SAndroid Build Coastguard Worker static void load_helper_sync(void)
202*d83cc019SAndroid Build Coastguard Worker {
203*d83cc019SAndroid Build Coastguard Worker 	bool dummy;
204*d83cc019SAndroid Build Coastguard Worker 
205*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(read(lh.link, &dummy, sizeof(dummy)), sizeof(dummy));
206*d83cc019SAndroid Build Coastguard Worker }
207*d83cc019SAndroid Build Coastguard Worker 
208*d83cc019SAndroid Build Coastguard Worker #define LOAD_HELPER_PAUSE_USEC 500
209*d83cc019SAndroid Build Coastguard Worker #define LOAD_HELPER_BO_SIZE (16*1024*1024)
load_helper_set_load(enum load load)210*d83cc019SAndroid Build Coastguard Worker static void load_helper_set_load(enum load load)
211*d83cc019SAndroid Build Coastguard Worker {
212*d83cc019SAndroid Build Coastguard Worker 	igt_assert(lh.igt_proc.running);
213*d83cc019SAndroid Build Coastguard Worker 
214*d83cc019SAndroid Build Coastguard Worker 	if (lh.load == load)
215*d83cc019SAndroid Build Coastguard Worker 		return;
216*d83cc019SAndroid Build Coastguard Worker 
217*d83cc019SAndroid Build Coastguard Worker 	lh.load = load;
218*d83cc019SAndroid Build Coastguard Worker 	kill(lh.igt_proc.pid, SIGUSR2);
219*d83cc019SAndroid Build Coastguard Worker 
220*d83cc019SAndroid Build Coastguard Worker 	/* wait for load-helper to switch */
221*d83cc019SAndroid Build Coastguard Worker 	load_helper_sync();
222*d83cc019SAndroid Build Coastguard Worker }
223*d83cc019SAndroid Build Coastguard Worker 
load_helper_run(enum load load)224*d83cc019SAndroid Build Coastguard Worker static void load_helper_run(enum load load)
225*d83cc019SAndroid Build Coastguard Worker {
226*d83cc019SAndroid Build Coastguard Worker 	int link[2];
227*d83cc019SAndroid Build Coastguard Worker 
228*d83cc019SAndroid Build Coastguard Worker 	/*
229*d83cc019SAndroid Build Coastguard Worker 	 * FIXME fork helpers won't get cleaned up when started from within a
230*d83cc019SAndroid Build Coastguard Worker 	 * subtest, so handle the case where it sticks around a bit too long.
231*d83cc019SAndroid Build Coastguard Worker 	 */
232*d83cc019SAndroid Build Coastguard Worker 	if (lh.igt_proc.running) {
233*d83cc019SAndroid Build Coastguard Worker 		load_helper_set_load(load);
234*d83cc019SAndroid Build Coastguard Worker 		return;
235*d83cc019SAndroid Build Coastguard Worker 	}
236*d83cc019SAndroid Build Coastguard Worker 
237*d83cc019SAndroid Build Coastguard Worker 	igt_require_gem(drm_fd);
238*d83cc019SAndroid Build Coastguard Worker 
239*d83cc019SAndroid Build Coastguard Worker 	lh.exit = false;
240*d83cc019SAndroid Build Coastguard Worker 	lh.load = load;
241*d83cc019SAndroid Build Coastguard Worker 	lh.signal = true;
242*d83cc019SAndroid Build Coastguard Worker 
243*d83cc019SAndroid Build Coastguard Worker 	pipe(link);
244*d83cc019SAndroid Build Coastguard Worker 	lh.link = link[1];
245*d83cc019SAndroid Build Coastguard Worker 
246*d83cc019SAndroid Build Coastguard Worker 	igt_fork_helper(&lh.igt_proc) {
247*d83cc019SAndroid Build Coastguard Worker 		igt_spin_t *spin[2] = {};
248*d83cc019SAndroid Build Coastguard Worker 		bool prev_load;
249*d83cc019SAndroid Build Coastguard Worker 		uint32_t handle;
250*d83cc019SAndroid Build Coastguard Worker 
251*d83cc019SAndroid Build Coastguard Worker 		signal(SIGUSR1, load_helper_signal_handler);
252*d83cc019SAndroid Build Coastguard Worker 		signal(SIGUSR2, load_helper_signal_handler);
253*d83cc019SAndroid Build Coastguard Worker 
254*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Applying %s load...\n", lh.load ? "high" : "low");
255*d83cc019SAndroid Build Coastguard Worker 
256*d83cc019SAndroid Build Coastguard Worker 		prev_load = lh.load == HIGH;
257*d83cc019SAndroid Build Coastguard Worker 		spin[0] = __igt_spin_new(drm_fd);
258*d83cc019SAndroid Build Coastguard Worker 		if (prev_load)
259*d83cc019SAndroid Build Coastguard Worker 			spin[1] = __igt_spin_new(drm_fd);
260*d83cc019SAndroid Build Coastguard Worker 		prev_load = !prev_load; /* send the initial signal */
261*d83cc019SAndroid Build Coastguard Worker 		while (!lh.exit) {
262*d83cc019SAndroid Build Coastguard Worker 			bool high_load;
263*d83cc019SAndroid Build Coastguard Worker 
264*d83cc019SAndroid Build Coastguard Worker 			handle = spin[0]->handle;
265*d83cc019SAndroid Build Coastguard Worker 			igt_spin_end(spin[0]);
266*d83cc019SAndroid Build Coastguard Worker 			while (gem_bo_busy(drm_fd, handle))
267*d83cc019SAndroid Build Coastguard Worker 				usleep(100);
268*d83cc019SAndroid Build Coastguard Worker 
269*d83cc019SAndroid Build Coastguard Worker 			igt_spin_free(drm_fd, spin[0]);
270*d83cc019SAndroid Build Coastguard Worker 			usleep(100);
271*d83cc019SAndroid Build Coastguard Worker 
272*d83cc019SAndroid Build Coastguard Worker 			high_load = lh.load == HIGH;
273*d83cc019SAndroid Build Coastguard Worker 			if (!high_load && spin[1]) {
274*d83cc019SAndroid Build Coastguard Worker 				igt_spin_free(drm_fd, spin[1]);
275*d83cc019SAndroid Build Coastguard Worker 				spin[1] = NULL;
276*d83cc019SAndroid Build Coastguard Worker 			} else {
277*d83cc019SAndroid Build Coastguard Worker 				spin[0] = spin[1];
278*d83cc019SAndroid Build Coastguard Worker 			}
279*d83cc019SAndroid Build Coastguard Worker 			spin[high_load] = __igt_spin_new(drm_fd);
280*d83cc019SAndroid Build Coastguard Worker 
281*d83cc019SAndroid Build Coastguard Worker 			if (lh.signal && high_load != prev_load) {
282*d83cc019SAndroid Build Coastguard Worker 				write(lh.link, &lh.signal, sizeof(lh.signal));
283*d83cc019SAndroid Build Coastguard Worker 				lh.signal = false;
284*d83cc019SAndroid Build Coastguard Worker 			}
285*d83cc019SAndroid Build Coastguard Worker 			prev_load = high_load;
286*d83cc019SAndroid Build Coastguard Worker 		}
287*d83cc019SAndroid Build Coastguard Worker 
288*d83cc019SAndroid Build Coastguard Worker 		handle = spin[0]->handle;
289*d83cc019SAndroid Build Coastguard Worker 		igt_spin_end(spin[0]);
290*d83cc019SAndroid Build Coastguard Worker 
291*d83cc019SAndroid Build Coastguard Worker 		if (spin[1]) {
292*d83cc019SAndroid Build Coastguard Worker 			handle = spin[1]->handle;
293*d83cc019SAndroid Build Coastguard Worker 			igt_spin_end(spin[1]);
294*d83cc019SAndroid Build Coastguard Worker 		}
295*d83cc019SAndroid Build Coastguard Worker 
296*d83cc019SAndroid Build Coastguard Worker 		/* Wait for completion without boosting */
297*d83cc019SAndroid Build Coastguard Worker 		usleep(1000);
298*d83cc019SAndroid Build Coastguard Worker 		while (gem_bo_busy(drm_fd, handle))
299*d83cc019SAndroid Build Coastguard Worker 			usleep(1000);
300*d83cc019SAndroid Build Coastguard Worker 
301*d83cc019SAndroid Build Coastguard Worker 		/*
302*d83cc019SAndroid Build Coastguard Worker 		 * Idle/boost logic is tied with request retirement.
303*d83cc019SAndroid Build Coastguard Worker 		 * Speed up detection of idle state and ensure deboost
304*d83cc019SAndroid Build Coastguard Worker 		 * after removing load.
305*d83cc019SAndroid Build Coastguard Worker 		 */
306*d83cc019SAndroid Build Coastguard Worker 		igt_drop_caches_set(drm_fd, DROP_RETIRE);
307*d83cc019SAndroid Build Coastguard Worker 
308*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(drm_fd, spin[1]);
309*d83cc019SAndroid Build Coastguard Worker 		igt_spin_free(drm_fd, spin[0]);
310*d83cc019SAndroid Build Coastguard Worker 	}
311*d83cc019SAndroid Build Coastguard Worker 
312*d83cc019SAndroid Build Coastguard Worker 	close(lh.link);
313*d83cc019SAndroid Build Coastguard Worker 	lh.link = link[0];
314*d83cc019SAndroid Build Coastguard Worker 
315*d83cc019SAndroid Build Coastguard Worker 	/* wait for our helper to complete its first round */
316*d83cc019SAndroid Build Coastguard Worker 	load_helper_sync();
317*d83cc019SAndroid Build Coastguard Worker }
318*d83cc019SAndroid Build Coastguard Worker 
load_helper_stop(void)319*d83cc019SAndroid Build Coastguard Worker static void load_helper_stop(void)
320*d83cc019SAndroid Build Coastguard Worker {
321*d83cc019SAndroid Build Coastguard Worker 	kill(lh.igt_proc.pid, SIGUSR1);
322*d83cc019SAndroid Build Coastguard Worker 	igt_assert(igt_wait_helper(&lh.igt_proc) == 0);
323*d83cc019SAndroid Build Coastguard Worker }
324*d83cc019SAndroid Build Coastguard Worker 
do_load_gpu(void)325*d83cc019SAndroid Build Coastguard Worker static void do_load_gpu(void)
326*d83cc019SAndroid Build Coastguard Worker {
327*d83cc019SAndroid Build Coastguard Worker 	load_helper_run(LOW);
328*d83cc019SAndroid Build Coastguard Worker 	nsleep(10000000);
329*d83cc019SAndroid Build Coastguard Worker 	load_helper_stop();
330*d83cc019SAndroid Build Coastguard Worker }
331*d83cc019SAndroid Build Coastguard Worker 
332*d83cc019SAndroid Build Coastguard Worker /* Return a frequency rounded by HW to the nearest supported value */
get_hw_rounded_freq(int target)333*d83cc019SAndroid Build Coastguard Worker static int get_hw_rounded_freq(int target)
334*d83cc019SAndroid Build Coastguard Worker {
335*d83cc019SAndroid Build Coastguard Worker 	int freqs[NUMFREQ];
336*d83cc019SAndroid Build Coastguard Worker 	int old_freq;
337*d83cc019SAndroid Build Coastguard Worker 	int idx;
338*d83cc019SAndroid Build Coastguard Worker 	int ret;
339*d83cc019SAndroid Build Coastguard Worker 
340*d83cc019SAndroid Build Coastguard Worker 	read_freqs(freqs);
341*d83cc019SAndroid Build Coastguard Worker 
342*d83cc019SAndroid Build Coastguard Worker 	if (freqs[MIN] > target)
343*d83cc019SAndroid Build Coastguard Worker 		idx = MIN;
344*d83cc019SAndroid Build Coastguard Worker 	else
345*d83cc019SAndroid Build Coastguard Worker 		idx = MAX;
346*d83cc019SAndroid Build Coastguard Worker 
347*d83cc019SAndroid Build Coastguard Worker 	old_freq = freqs[idx];
348*d83cc019SAndroid Build Coastguard Worker 	writeval_nocheck(sysfs_files[idx].filp, target);
349*d83cc019SAndroid Build Coastguard Worker 	read_freqs(freqs);
350*d83cc019SAndroid Build Coastguard Worker 	ret = freqs[idx];
351*d83cc019SAndroid Build Coastguard Worker 	writeval_nocheck(sysfs_files[idx].filp, old_freq);
352*d83cc019SAndroid Build Coastguard Worker 
353*d83cc019SAndroid Build Coastguard Worker 	return ret;
354*d83cc019SAndroid Build Coastguard Worker }
355*d83cc019SAndroid Build Coastguard Worker 
356*d83cc019SAndroid Build Coastguard Worker /*
357*d83cc019SAndroid Build Coastguard Worker  * Modify softlimit MIN and MAX freqs to valid and invalid levels. Depending
358*d83cc019SAndroid Build Coastguard Worker  * on subtest run different check after each modification.
359*d83cc019SAndroid Build Coastguard Worker  */
min_max_config(void (* check)(void),bool load_gpu)360*d83cc019SAndroid Build Coastguard Worker static void min_max_config(void (*check)(void), bool load_gpu)
361*d83cc019SAndroid Build Coastguard Worker {
362*d83cc019SAndroid Build Coastguard Worker 	int fmid = (origfreqs[RPn] + origfreqs[RP0]) / 2;
363*d83cc019SAndroid Build Coastguard Worker 
364*d83cc019SAndroid Build Coastguard Worker 	/*
365*d83cc019SAndroid Build Coastguard Worker 	 * hw (and so kernel) rounds to the nearest value supported by
366*d83cc019SAndroid Build Coastguard Worker 	 * the given platform.
367*d83cc019SAndroid Build Coastguard Worker 	 */
368*d83cc019SAndroid Build Coastguard Worker 	fmid = get_hw_rounded_freq(fmid);
369*d83cc019SAndroid Build Coastguard Worker 
370*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nCheck original min and max...\n");
371*d83cc019SAndroid Build Coastguard Worker 	if (load_gpu)
372*d83cc019SAndroid Build Coastguard Worker 		do_load_gpu();
373*d83cc019SAndroid Build Coastguard Worker 	check();
374*d83cc019SAndroid Build Coastguard Worker 
375*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nSet min=RPn and max=RP0...\n");
376*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MIN].filp, origfreqs[RPn]);
377*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MAX].filp, origfreqs[RP0]);
378*d83cc019SAndroid Build Coastguard Worker 	if (load_gpu)
379*d83cc019SAndroid Build Coastguard Worker 		do_load_gpu();
380*d83cc019SAndroid Build Coastguard Worker 	check();
381*d83cc019SAndroid Build Coastguard Worker 
382*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nIncrease min to midpoint...\n");
383*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MIN].filp, fmid);
384*d83cc019SAndroid Build Coastguard Worker 	if (load_gpu)
385*d83cc019SAndroid Build Coastguard Worker 		do_load_gpu();
386*d83cc019SAndroid Build Coastguard Worker 	check();
387*d83cc019SAndroid Build Coastguard Worker 
388*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nIncrease min to RP0...\n");
389*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MIN].filp, origfreqs[RP0]);
390*d83cc019SAndroid Build Coastguard Worker 	if (load_gpu)
391*d83cc019SAndroid Build Coastguard Worker 		do_load_gpu();
392*d83cc019SAndroid Build Coastguard Worker 	check();
393*d83cc019SAndroid Build Coastguard Worker 
394*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nIncrease min above RP0 (invalid)...\n");
395*d83cc019SAndroid Build Coastguard Worker 	writeval_inval(sysfs_files[MIN].filp, origfreqs[RP0] + 1000);
396*d83cc019SAndroid Build Coastguard Worker 	check();
397*d83cc019SAndroid Build Coastguard Worker 
398*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nDecrease max to RPn (invalid)...\n");
399*d83cc019SAndroid Build Coastguard Worker 	writeval_inval(sysfs_files[MAX].filp, origfreqs[RPn]);
400*d83cc019SAndroid Build Coastguard Worker 	check();
401*d83cc019SAndroid Build Coastguard Worker 
402*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nDecrease min to midpoint...\n");
403*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MIN].filp, fmid);
404*d83cc019SAndroid Build Coastguard Worker 	if (load_gpu)
405*d83cc019SAndroid Build Coastguard Worker 		do_load_gpu();
406*d83cc019SAndroid Build Coastguard Worker 	check();
407*d83cc019SAndroid Build Coastguard Worker 
408*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nDecrease min to RPn...\n");
409*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MIN].filp, origfreqs[RPn]);
410*d83cc019SAndroid Build Coastguard Worker 	if (load_gpu)
411*d83cc019SAndroid Build Coastguard Worker 		do_load_gpu();
412*d83cc019SAndroid Build Coastguard Worker 	check();
413*d83cc019SAndroid Build Coastguard Worker 
414*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nDecrease min below RPn (invalid)...\n");
415*d83cc019SAndroid Build Coastguard Worker 	writeval_inval(sysfs_files[MIN].filp, 0);
416*d83cc019SAndroid Build Coastguard Worker 	check();
417*d83cc019SAndroid Build Coastguard Worker 
418*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nDecrease max to midpoint...\n");
419*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MAX].filp, fmid);
420*d83cc019SAndroid Build Coastguard Worker 	check();
421*d83cc019SAndroid Build Coastguard Worker 
422*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nDecrease max to RPn...\n");
423*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MAX].filp, origfreqs[RPn]);
424*d83cc019SAndroid Build Coastguard Worker 	check();
425*d83cc019SAndroid Build Coastguard Worker 
426*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nDecrease max below RPn (invalid)...\n");
427*d83cc019SAndroid Build Coastguard Worker 	writeval_inval(sysfs_files[MAX].filp, 0);
428*d83cc019SAndroid Build Coastguard Worker 	check();
429*d83cc019SAndroid Build Coastguard Worker 
430*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nIncrease min to RP0 (invalid)...\n");
431*d83cc019SAndroid Build Coastguard Worker 	writeval_inval(sysfs_files[MIN].filp, origfreqs[RP0]);
432*d83cc019SAndroid Build Coastguard Worker 	check();
433*d83cc019SAndroid Build Coastguard Worker 
434*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nIncrease max to midpoint...\n");
435*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MAX].filp, fmid);
436*d83cc019SAndroid Build Coastguard Worker 	check();
437*d83cc019SAndroid Build Coastguard Worker 
438*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nIncrease max to RP0...\n");
439*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MAX].filp, origfreqs[RP0]);
440*d83cc019SAndroid Build Coastguard Worker 	check();
441*d83cc019SAndroid Build Coastguard Worker 
442*d83cc019SAndroid Build Coastguard Worker 	igt_debug("\nIncrease max above RP0 (invalid)...\n");
443*d83cc019SAndroid Build Coastguard Worker 	writeval_inval(sysfs_files[MAX].filp, origfreqs[RP0] + 1000);
444*d83cc019SAndroid Build Coastguard Worker 	check();
445*d83cc019SAndroid Build Coastguard Worker 
446*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MIN].filp, origfreqs[MIN]);
447*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MAX].filp, origfreqs[MAX]);
448*d83cc019SAndroid Build Coastguard Worker }
449*d83cc019SAndroid Build Coastguard Worker 
basic_check(void)450*d83cc019SAndroid Build Coastguard Worker static void basic_check(void)
451*d83cc019SAndroid Build Coastguard Worker {
452*d83cc019SAndroid Build Coastguard Worker 	int freqs[NUMFREQ];
453*d83cc019SAndroid Build Coastguard Worker 
454*d83cc019SAndroid Build Coastguard Worker 	read_freqs(freqs);
455*d83cc019SAndroid Build Coastguard Worker 	dump(freqs);
456*d83cc019SAndroid Build Coastguard Worker 	check_freq_constraints(freqs);
457*d83cc019SAndroid Build Coastguard Worker }
458*d83cc019SAndroid Build Coastguard Worker 
459*d83cc019SAndroid Build Coastguard Worker #define IDLE_WAIT_TIMESTEP_MSEC 250
460*d83cc019SAndroid Build Coastguard Worker #define IDLE_WAIT_TIMEOUT_MSEC 2500
idle_check(void)461*d83cc019SAndroid Build Coastguard Worker static void idle_check(void)
462*d83cc019SAndroid Build Coastguard Worker {
463*d83cc019SAndroid Build Coastguard Worker 	int freqs[NUMFREQ];
464*d83cc019SAndroid Build Coastguard Worker 	int wait = 0;
465*d83cc019SAndroid Build Coastguard Worker 
466*d83cc019SAndroid Build Coastguard Worker 	/* Monitor frequencies until cur settles down to min, which should
467*d83cc019SAndroid Build Coastguard Worker 	 * happen within the allotted time */
468*d83cc019SAndroid Build Coastguard Worker 	do {
469*d83cc019SAndroid Build Coastguard Worker 		read_freqs(freqs);
470*d83cc019SAndroid Build Coastguard Worker 		dump(freqs);
471*d83cc019SAndroid Build Coastguard Worker 		check_freq_constraints(freqs);
472*d83cc019SAndroid Build Coastguard Worker 		if (freqs[CUR] == freqs[RPn])
473*d83cc019SAndroid Build Coastguard Worker 			break;
474*d83cc019SAndroid Build Coastguard Worker 		usleep(1000 * IDLE_WAIT_TIMESTEP_MSEC);
475*d83cc019SAndroid Build Coastguard Worker 		wait += IDLE_WAIT_TIMESTEP_MSEC;
476*d83cc019SAndroid Build Coastguard Worker 	} while (wait < IDLE_WAIT_TIMEOUT_MSEC);
477*d83cc019SAndroid Build Coastguard Worker 
478*d83cc019SAndroid Build Coastguard Worker 	igt_debugfs_dump(drm_fd, "i915_rps_boost_info");
479*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(freqs[CUR], freqs[RPn]);
480*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Required %d msec to reach cur=idle\n", wait);
481*d83cc019SAndroid Build Coastguard Worker }
482*d83cc019SAndroid Build Coastguard Worker 
483*d83cc019SAndroid Build Coastguard Worker #define LOADED_WAIT_TIMESTEP_MSEC 100
484*d83cc019SAndroid Build Coastguard Worker #define LOADED_WAIT_TIMEOUT_MSEC 3000
loaded_check(void)485*d83cc019SAndroid Build Coastguard Worker static void loaded_check(void)
486*d83cc019SAndroid Build Coastguard Worker {
487*d83cc019SAndroid Build Coastguard Worker 	int freqs[NUMFREQ];
488*d83cc019SAndroid Build Coastguard Worker 	int wait = 0;
489*d83cc019SAndroid Build Coastguard Worker 
490*d83cc019SAndroid Build Coastguard Worker 	/* Monitor frequencies until cur increases to max, which should
491*d83cc019SAndroid Build Coastguard Worker 	 * happen within the allotted time */
492*d83cc019SAndroid Build Coastguard Worker 	do {
493*d83cc019SAndroid Build Coastguard Worker 		read_freqs(freqs);
494*d83cc019SAndroid Build Coastguard Worker 		dump(freqs);
495*d83cc019SAndroid Build Coastguard Worker 		check_freq_constraints(freqs);
496*d83cc019SAndroid Build Coastguard Worker 		if (freqs[CUR] >= freqs[MAX])
497*d83cc019SAndroid Build Coastguard Worker 			break;
498*d83cc019SAndroid Build Coastguard Worker 		usleep(1000 * LOADED_WAIT_TIMESTEP_MSEC);
499*d83cc019SAndroid Build Coastguard Worker 		wait += LOADED_WAIT_TIMESTEP_MSEC;
500*d83cc019SAndroid Build Coastguard Worker 	} while (wait < LOADED_WAIT_TIMEOUT_MSEC);
501*d83cc019SAndroid Build Coastguard Worker 
502*d83cc019SAndroid Build Coastguard Worker 	igt_debugfs_dump(drm_fd, "i915_rps_boost_info");
503*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lte(freqs[MAX], freqs[CUR]);
504*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Required %d msec to reach cur=max\n", wait);
505*d83cc019SAndroid Build Coastguard Worker }
506*d83cc019SAndroid Build Coastguard Worker 
507*d83cc019SAndroid Build Coastguard Worker #define STABILIZE_WAIT_TIMESTEP_MSEC 250
508*d83cc019SAndroid Build Coastguard Worker #define STABILIZE_WAIT_TIMEOUT_MSEC 15000
stabilize_check(int * out)509*d83cc019SAndroid Build Coastguard Worker static void stabilize_check(int *out)
510*d83cc019SAndroid Build Coastguard Worker {
511*d83cc019SAndroid Build Coastguard Worker 	int freqs[NUMFREQ];
512*d83cc019SAndroid Build Coastguard Worker 	int wait = 0;
513*d83cc019SAndroid Build Coastguard Worker 
514*d83cc019SAndroid Build Coastguard Worker 	/* Monitor frequencies until HW will stabilize cur frequency.
515*d83cc019SAndroid Build Coastguard Worker 	 * It should happen within allotted time */
516*d83cc019SAndroid Build Coastguard Worker 	read_freqs(freqs);
517*d83cc019SAndroid Build Coastguard Worker 	dump(freqs);
518*d83cc019SAndroid Build Coastguard Worker 	usleep(1000 * STABILIZE_WAIT_TIMESTEP_MSEC);
519*d83cc019SAndroid Build Coastguard Worker 	do {
520*d83cc019SAndroid Build Coastguard Worker 		read_freqs(out);
521*d83cc019SAndroid Build Coastguard Worker 		dump(out);
522*d83cc019SAndroid Build Coastguard Worker 
523*d83cc019SAndroid Build Coastguard Worker 		if (memcmp(freqs, out, sizeof(freqs)) == 0)
524*d83cc019SAndroid Build Coastguard Worker 			break;
525*d83cc019SAndroid Build Coastguard Worker 
526*d83cc019SAndroid Build Coastguard Worker 		memcpy(freqs, out, sizeof(freqs));
527*d83cc019SAndroid Build Coastguard Worker 		wait += STABILIZE_WAIT_TIMESTEP_MSEC;
528*d83cc019SAndroid Build Coastguard Worker 	} while (wait < STABILIZE_WAIT_TIMEOUT_MSEC);
529*d83cc019SAndroid Build Coastguard Worker 
530*d83cc019SAndroid Build Coastguard Worker 	igt_debugfs_dump(drm_fd, "i915_rps_boost_info");
531*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Waited %d msec to stabilize cur\n", wait);
532*d83cc019SAndroid Build Coastguard Worker }
533*d83cc019SAndroid Build Coastguard Worker 
resubmit_batch(int fd,uint32_t handle,int count)534*d83cc019SAndroid Build Coastguard Worker static void resubmit_batch(int fd, uint32_t handle, int count)
535*d83cc019SAndroid Build Coastguard Worker {
536*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_exec_object2 obj = {
537*d83cc019SAndroid Build Coastguard Worker 		.handle = handle
538*d83cc019SAndroid Build Coastguard Worker 	};
539*d83cc019SAndroid Build Coastguard Worker 	struct drm_i915_gem_execbuffer2 eb = {
540*d83cc019SAndroid Build Coastguard Worker 		.buffer_count = 1,
541*d83cc019SAndroid Build Coastguard Worker 		.buffers_ptr = to_user_pointer(&obj),
542*d83cc019SAndroid Build Coastguard Worker 	};
543*d83cc019SAndroid Build Coastguard Worker 	while (count--)
544*d83cc019SAndroid Build Coastguard Worker 		gem_execbuf(fd, &eb);
545*d83cc019SAndroid Build Coastguard Worker }
546*d83cc019SAndroid Build Coastguard Worker 
boost_freq(int fd,int * boost_freqs)547*d83cc019SAndroid Build Coastguard Worker static void boost_freq(int fd, int *boost_freqs)
548*d83cc019SAndroid Build Coastguard Worker {
549*d83cc019SAndroid Build Coastguard Worker 	int64_t timeout = 1;
550*d83cc019SAndroid Build Coastguard Worker 	igt_spin_t *load;
551*d83cc019SAndroid Build Coastguard Worker 
552*d83cc019SAndroid Build Coastguard Worker 	load = igt_spin_new(fd);
553*d83cc019SAndroid Build Coastguard Worker 	resubmit_batch(fd, load->handle, 16);
554*d83cc019SAndroid Build Coastguard Worker 
555*d83cc019SAndroid Build Coastguard Worker 	/* Waiting will grant us a boost to maximum */
556*d83cc019SAndroid Build Coastguard Worker 	gem_wait(fd, load->handle, &timeout);
557*d83cc019SAndroid Build Coastguard Worker 
558*d83cc019SAndroid Build Coastguard Worker 	read_freqs(boost_freqs);
559*d83cc019SAndroid Build Coastguard Worker 	dump(boost_freqs);
560*d83cc019SAndroid Build Coastguard Worker 
561*d83cc019SAndroid Build Coastguard Worker 	/* Avoid downlocking till boost request is pending */
562*d83cc019SAndroid Build Coastguard Worker 	igt_spin_end(load);
563*d83cc019SAndroid Build Coastguard Worker 	gem_sync(fd, load->handle);
564*d83cc019SAndroid Build Coastguard Worker 	igt_spin_free(fd, load);
565*d83cc019SAndroid Build Coastguard Worker }
566*d83cc019SAndroid Build Coastguard Worker 
waitboost(int fd,bool reset)567*d83cc019SAndroid Build Coastguard Worker static void waitboost(int fd, bool reset)
568*d83cc019SAndroid Build Coastguard Worker {
569*d83cc019SAndroid Build Coastguard Worker 	int pre_freqs[NUMFREQ];
570*d83cc019SAndroid Build Coastguard Worker 	int boost_freqs[NUMFREQ];
571*d83cc019SAndroid Build Coastguard Worker 	int post_freqs[NUMFREQ];
572*d83cc019SAndroid Build Coastguard Worker 	int fmid = (origfreqs[RPn] + origfreqs[RP0]) / 2;
573*d83cc019SAndroid Build Coastguard Worker 	fmid = get_hw_rounded_freq(fmid);
574*d83cc019SAndroid Build Coastguard Worker 
575*d83cc019SAndroid Build Coastguard Worker 	load_helper_run(LOW);
576*d83cc019SAndroid Build Coastguard Worker 
577*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Apply low load...\n");
578*d83cc019SAndroid Build Coastguard Worker 	sleep(1);
579*d83cc019SAndroid Build Coastguard Worker 	stabilize_check(pre_freqs);
580*d83cc019SAndroid Build Coastguard Worker 
581*d83cc019SAndroid Build Coastguard Worker 	if (reset) {
582*d83cc019SAndroid Build Coastguard Worker 		igt_debug("Reset gpu...\n");
583*d83cc019SAndroid Build Coastguard Worker 		igt_force_gpu_reset(fd);
584*d83cc019SAndroid Build Coastguard Worker 		sleep(1);
585*d83cc019SAndroid Build Coastguard Worker 	}
586*d83cc019SAndroid Build Coastguard Worker 
587*d83cc019SAndroid Build Coastguard Worker 	/* Set max freq to less than boost freq */
588*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MAX].filp, fmid);
589*d83cc019SAndroid Build Coastguard Worker 
590*d83cc019SAndroid Build Coastguard Worker 	/* When we wait upon the GPU, we want to temporarily boost it
591*d83cc019SAndroid Build Coastguard Worker 	 * to maximum.
592*d83cc019SAndroid Build Coastguard Worker 	 */
593*d83cc019SAndroid Build Coastguard Worker 	boost_freq(fd, boost_freqs);
594*d83cc019SAndroid Build Coastguard Worker 
595*d83cc019SAndroid Build Coastguard Worker 	/* Set max freq to original softmax */
596*d83cc019SAndroid Build Coastguard Worker 	writeval(sysfs_files[MAX].filp, origfreqs[MAX]);
597*d83cc019SAndroid Build Coastguard Worker 
598*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Apply low load again...\n");
599*d83cc019SAndroid Build Coastguard Worker 	sleep(1);
600*d83cc019SAndroid Build Coastguard Worker 	stabilize_check(post_freqs);
601*d83cc019SAndroid Build Coastguard Worker 
602*d83cc019SAndroid Build Coastguard Worker 	igt_debug("Removing load...\n");
603*d83cc019SAndroid Build Coastguard Worker 	load_helper_stop();
604*d83cc019SAndroid Build Coastguard Worker 	idle_check();
605*d83cc019SAndroid Build Coastguard Worker 
606*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lt(pre_freqs[CUR], pre_freqs[MAX]);
607*d83cc019SAndroid Build Coastguard Worker 	igt_assert_eq(boost_freqs[CUR], boost_freqs[BOOST]);
608*d83cc019SAndroid Build Coastguard Worker 	igt_assert_lt(post_freqs[CUR], post_freqs[MAX]);
609*d83cc019SAndroid Build Coastguard Worker }
610*d83cc019SAndroid Build Coastguard Worker 
pm_rps_exit_handler(int sig)611*d83cc019SAndroid Build Coastguard Worker static void pm_rps_exit_handler(int sig)
612*d83cc019SAndroid Build Coastguard Worker {
613*d83cc019SAndroid Build Coastguard Worker 	if (origfreqs[MIN] > readval(sysfs_files[MAX].filp)) {
614*d83cc019SAndroid Build Coastguard Worker 		writeval(sysfs_files[MAX].filp, origfreqs[MAX]);
615*d83cc019SAndroid Build Coastguard Worker 		writeval(sysfs_files[MIN].filp, origfreqs[MIN]);
616*d83cc019SAndroid Build Coastguard Worker 	} else {
617*d83cc019SAndroid Build Coastguard Worker 		writeval(sysfs_files[MIN].filp, origfreqs[MIN]);
618*d83cc019SAndroid Build Coastguard Worker 		writeval(sysfs_files[MAX].filp, origfreqs[MAX]);
619*d83cc019SAndroid Build Coastguard Worker 	}
620*d83cc019SAndroid Build Coastguard Worker 
621*d83cc019SAndroid Build Coastguard Worker 	if (lh.igt_proc.running)
622*d83cc019SAndroid Build Coastguard Worker 		load_helper_stop();
623*d83cc019SAndroid Build Coastguard Worker 
624*d83cc019SAndroid Build Coastguard Worker 	close(drm_fd);
625*d83cc019SAndroid Build Coastguard Worker }
626*d83cc019SAndroid Build Coastguard Worker 
627*d83cc019SAndroid Build Coastguard Worker igt_main
628*d83cc019SAndroid Build Coastguard Worker {
629*d83cc019SAndroid Build Coastguard Worker 	igt_skip_on_simulation();
630*d83cc019SAndroid Build Coastguard Worker 
631*d83cc019SAndroid Build Coastguard Worker 	igt_fixture {
632*d83cc019SAndroid Build Coastguard Worker 		struct sysfs_file *sysfs_file = sysfs_files;
633*d83cc019SAndroid Build Coastguard Worker 		char sysfs_path[80];
634*d83cc019SAndroid Build Coastguard Worker 		int ret;
635*d83cc019SAndroid Build Coastguard Worker 
636*d83cc019SAndroid Build Coastguard Worker 		/* Use drm_open_driver to verify device existence */
637*d83cc019SAndroid Build Coastguard Worker 		drm_fd = drm_open_driver(DRIVER_INTEL);
638*d83cc019SAndroid Build Coastguard Worker 		igt_require_gem(drm_fd);
639*d83cc019SAndroid Build Coastguard Worker 		igt_require(gem_can_store_dword(drm_fd, 0));
640*d83cc019SAndroid Build Coastguard Worker 		igt_assert(igt_sysfs_path(drm_fd, sysfs_path,
641*d83cc019SAndroid Build Coastguard Worker 					  sizeof(sysfs_path)));
642*d83cc019SAndroid Build Coastguard Worker 
643*d83cc019SAndroid Build Coastguard Worker 		do {
644*d83cc019SAndroid Build Coastguard Worker 			int val = -1;
645*d83cc019SAndroid Build Coastguard Worker 			char *path;
646*d83cc019SAndroid Build Coastguard Worker 
647*d83cc019SAndroid Build Coastguard Worker 			ret = asprintf(&path, "%s/gt_%s_freq_mhz",
648*d83cc019SAndroid Build Coastguard Worker 				       sysfs_path, sysfs_file->name);
649*d83cc019SAndroid Build Coastguard Worker 			igt_assert(ret != -1);
650*d83cc019SAndroid Build Coastguard Worker 			sysfs_file->filp = fopen(path, sysfs_file->mode);
651*d83cc019SAndroid Build Coastguard Worker 			igt_require(sysfs_file->filp);
652*d83cc019SAndroid Build Coastguard Worker 			setbuf(sysfs_file->filp, NULL);
653*d83cc019SAndroid Build Coastguard Worker 
654*d83cc019SAndroid Build Coastguard Worker 			val = readval(sysfs_file->filp);
655*d83cc019SAndroid Build Coastguard Worker 			igt_assert(val >= 0);
656*d83cc019SAndroid Build Coastguard Worker 			sysfs_file++;
657*d83cc019SAndroid Build Coastguard Worker 		} while (sysfs_file->name != NULL);
658*d83cc019SAndroid Build Coastguard Worker 
659*d83cc019SAndroid Build Coastguard Worker 		read_freqs(origfreqs);
660*d83cc019SAndroid Build Coastguard Worker 
661*d83cc019SAndroid Build Coastguard Worker 		igt_install_exit_handler(pm_rps_exit_handler);
662*d83cc019SAndroid Build Coastguard Worker 	}
663*d83cc019SAndroid Build Coastguard Worker 
664*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("basic-api")
665*d83cc019SAndroid Build Coastguard Worker 		min_max_config(basic_check, false);
666*d83cc019SAndroid Build Coastguard Worker 
667*d83cc019SAndroid Build Coastguard Worker 	/* Verify the constraints, check if we can reach idle */
668*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("min-max-config-idle")
669*d83cc019SAndroid Build Coastguard Worker 		min_max_config(idle_check, true);
670*d83cc019SAndroid Build Coastguard Worker 
671*d83cc019SAndroid Build Coastguard Worker 	/* Verify the constraints with high load, check if we can reach max */
672*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("min-max-config-loaded") {
673*d83cc019SAndroid Build Coastguard Worker 		load_helper_run(HIGH);
674*d83cc019SAndroid Build Coastguard Worker 		min_max_config(loaded_check, false);
675*d83cc019SAndroid Build Coastguard Worker 		load_helper_stop();
676*d83cc019SAndroid Build Coastguard Worker 	}
677*d83cc019SAndroid Build Coastguard Worker 
678*d83cc019SAndroid Build Coastguard Worker 	/* Checks if we achieve boost using gem_wait */
679*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("waitboost")
680*d83cc019SAndroid Build Coastguard Worker 		waitboost(drm_fd, false);
681*d83cc019SAndroid Build Coastguard Worker 
682*d83cc019SAndroid Build Coastguard Worker 	/* Test boost frequency after GPU reset */
683*d83cc019SAndroid Build Coastguard Worker 	igt_subtest("reset") {
684*d83cc019SAndroid Build Coastguard Worker 		igt_hang_t hang = igt_allow_hang(drm_fd, 0, 0);
685*d83cc019SAndroid Build Coastguard Worker 		waitboost(drm_fd, true);
686*d83cc019SAndroid Build Coastguard Worker 		igt_disallow_hang(drm_fd, hang);
687*d83cc019SAndroid Build Coastguard Worker 	}
688*d83cc019SAndroid Build Coastguard Worker }
689