xref: /aosp_15_r20/external/igt-gpu-tools/lib/igt_gpu_power.c (revision d83cc019efdc2edc6c4b16e9034a3ceb8d35d77c)
1*d83cc019SAndroid Build Coastguard Worker #include <ctype.h>
2*d83cc019SAndroid Build Coastguard Worker #include <errno.h>
3*d83cc019SAndroid Build Coastguard Worker #include <fcntl.h>
4*d83cc019SAndroid Build Coastguard Worker #include <locale.h>
5*d83cc019SAndroid Build Coastguard Worker #include <math.h>
6*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
7*d83cc019SAndroid Build Coastguard Worker #include <inttypes.h>
8*d83cc019SAndroid Build Coastguard Worker 
9*d83cc019SAndroid Build Coastguard Worker #include "igt_gpu_power.h"
10*d83cc019SAndroid Build Coastguard Worker #include "igt_perf.h"
11*d83cc019SAndroid Build Coastguard Worker #include "igt_sysfs.h"
12*d83cc019SAndroid Build Coastguard Worker 
13*d83cc019SAndroid Build Coastguard Worker struct rapl {
14*d83cc019SAndroid Build Coastguard Worker 	uint64_t power, type;
15*d83cc019SAndroid Build Coastguard Worker 	double scale;
16*d83cc019SAndroid Build Coastguard Worker };
17*d83cc019SAndroid Build Coastguard Worker 
rapl_parse(struct rapl * r)18*d83cc019SAndroid Build Coastguard Worker static int rapl_parse(struct rapl *r)
19*d83cc019SAndroid Build Coastguard Worker {
20*d83cc019SAndroid Build Coastguard Worker 	locale_t locale, oldlocale;
21*d83cc019SAndroid Build Coastguard Worker 	bool result;
22*d83cc019SAndroid Build Coastguard Worker 	int dir;
23*d83cc019SAndroid Build Coastguard Worker 
24*d83cc019SAndroid Build Coastguard Worker 	memset(r, 0, sizeof(*r));
25*d83cc019SAndroid Build Coastguard Worker 
26*d83cc019SAndroid Build Coastguard Worker 	dir = open("/sys/devices/power", O_RDONLY);
27*d83cc019SAndroid Build Coastguard Worker 	if (dir < 0)
28*d83cc019SAndroid Build Coastguard Worker 		return -errno;
29*d83cc019SAndroid Build Coastguard Worker 
30*d83cc019SAndroid Build Coastguard Worker 	/* Replace user environment with plain C to match kernel format */
31*d83cc019SAndroid Build Coastguard Worker 	locale = newlocale(LC_ALL, "C", 0);
32*d83cc019SAndroid Build Coastguard Worker 	oldlocale = uselocale(locale);
33*d83cc019SAndroid Build Coastguard Worker 
34*d83cc019SAndroid Build Coastguard Worker 	result = true;
35*d83cc019SAndroid Build Coastguard Worker 	result &= igt_sysfs_scanf(dir, "type",
36*d83cc019SAndroid Build Coastguard Worker 				  "%"PRIu64, &r->type) == 1;
37*d83cc019SAndroid Build Coastguard Worker 	result &= igt_sysfs_scanf(dir, "events/energy-gpu",
38*d83cc019SAndroid Build Coastguard Worker 				  "event=%"PRIx64, &r->power) == 1;
39*d83cc019SAndroid Build Coastguard Worker 	result &= igt_sysfs_scanf(dir, "events/energy-gpu.scale",
40*d83cc019SAndroid Build Coastguard Worker 				  "%lf", &r->scale) == 1;
41*d83cc019SAndroid Build Coastguard Worker 
42*d83cc019SAndroid Build Coastguard Worker 	uselocale(oldlocale);
43*d83cc019SAndroid Build Coastguard Worker 	freelocale(locale);
44*d83cc019SAndroid Build Coastguard Worker 
45*d83cc019SAndroid Build Coastguard Worker 	close(dir);
46*d83cc019SAndroid Build Coastguard Worker 
47*d83cc019SAndroid Build Coastguard Worker 	if (!result)
48*d83cc019SAndroid Build Coastguard Worker 		return -EINVAL;
49*d83cc019SAndroid Build Coastguard Worker 
50*d83cc019SAndroid Build Coastguard Worker 	if (isnan(r->scale) || !r->scale)
51*d83cc019SAndroid Build Coastguard Worker 		return -ERANGE;
52*d83cc019SAndroid Build Coastguard Worker 
53*d83cc019SAndroid Build Coastguard Worker 	return 0;
54*d83cc019SAndroid Build Coastguard Worker }
55*d83cc019SAndroid Build Coastguard Worker 
gpu_power_open(struct gpu_power * power)56*d83cc019SAndroid Build Coastguard Worker int gpu_power_open(struct gpu_power *power)
57*d83cc019SAndroid Build Coastguard Worker {
58*d83cc019SAndroid Build Coastguard Worker 	struct rapl r;
59*d83cc019SAndroid Build Coastguard Worker 
60*d83cc019SAndroid Build Coastguard Worker 	power->fd = rapl_parse(&r);
61*d83cc019SAndroid Build Coastguard Worker 	if (power->fd < 0)
62*d83cc019SAndroid Build Coastguard Worker 		goto err;
63*d83cc019SAndroid Build Coastguard Worker 
64*d83cc019SAndroid Build Coastguard Worker 	power->fd = igt_perf_open(r.type, r.power);
65*d83cc019SAndroid Build Coastguard Worker 	if (power->fd < 0) {
66*d83cc019SAndroid Build Coastguard Worker 		power->fd = -errno;
67*d83cc019SAndroid Build Coastguard Worker 		goto err;
68*d83cc019SAndroid Build Coastguard Worker 	}
69*d83cc019SAndroid Build Coastguard Worker 
70*d83cc019SAndroid Build Coastguard Worker 	power->scale = r.scale;
71*d83cc019SAndroid Build Coastguard Worker 
72*d83cc019SAndroid Build Coastguard Worker 	return 0;
73*d83cc019SAndroid Build Coastguard Worker 
74*d83cc019SAndroid Build Coastguard Worker err:
75*d83cc019SAndroid Build Coastguard Worker 	errno = 0;
76*d83cc019SAndroid Build Coastguard Worker 	return power->fd;
77*d83cc019SAndroid Build Coastguard Worker }
78*d83cc019SAndroid Build Coastguard Worker 
gpu_power_read(struct gpu_power * power,struct gpu_power_sample * s)79*d83cc019SAndroid Build Coastguard Worker bool gpu_power_read(struct gpu_power *power, struct gpu_power_sample *s)
80*d83cc019SAndroid Build Coastguard Worker {
81*d83cc019SAndroid Build Coastguard Worker 	return read(power->fd, s, sizeof(*s)) == sizeof(*s);
82*d83cc019SAndroid Build Coastguard Worker }
83*d83cc019SAndroid Build Coastguard Worker 
gpu_power_close(struct gpu_power * power)84*d83cc019SAndroid Build Coastguard Worker void gpu_power_close(struct gpu_power *power)
85*d83cc019SAndroid Build Coastguard Worker {
86*d83cc019SAndroid Build Coastguard Worker 	close(power->fd);
87*d83cc019SAndroid Build Coastguard Worker }
88