xref: /linux/tools/power/cpupower/utils/cpupower-set.c (revision 26d6ed49cd008a326063d82bd731c2a82f2f4378)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  *  (C) 2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
4  */
5 
6 
7 #include <unistd.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <errno.h>
11 #include <string.h>
12 #include <getopt.h>
13 #include <sys/utsname.h>
14 
15 #include "helpers/helpers.h"
16 #include "helpers/sysfs.h"
17 #include "helpers/bitmask.h"
18 
19 static struct option set_opts[] = {
20 	{"perf-bias", required_argument, NULL, 'b'},
21 	{"epp", required_argument, NULL, 'e'},
22 	{"amd-pstate-mode", required_argument, NULL, 'm'},
23 	{"turbo-boost", required_argument, NULL, 't'},
24 	{"boost", required_argument, NULL, 't'},
25 	{ },
26 };
27 
print_wrong_arg_exit(void)28 static void print_wrong_arg_exit(void)
29 {
30 	printf(_("invalid or unknown argument\n"));
31 	exit(EXIT_FAILURE);
32 }
33 
cmd_set(int argc,char ** argv)34 int cmd_set(int argc, char **argv)
35 {
36 	extern char *optarg;
37 	extern int optind, opterr, optopt;
38 	unsigned int cpu;
39 	struct utsname uts;
40 
41 	union {
42 		struct {
43 			int perf_bias:1;
44 			int epp:1;
45 			int mode:1;
46 			int turbo_boost:1;
47 		};
48 		int params;
49 	} params;
50 	int perf_bias = 0, turbo_boost = 1;
51 	int ret = 0;
52 	char epp[30], mode[20];
53 
54 	ret = uname(&uts);
55 	if (!ret && (!strcmp(uts.machine, "ppc64le") ||
56 		     !strcmp(uts.machine, "ppc64"))) {
57 		fprintf(stderr, _("Subcommand not supported on POWER.\n"));
58 		return ret;
59 	}
60 
61 	setlocale(LC_ALL, "");
62 	textdomain(PACKAGE);
63 
64 	params.params = 0;
65 	/* parameter parsing */
66 	while ((ret = getopt_long(argc, argv, "b:e:m:t:",
67 				  set_opts, NULL)) != -1) {
68 		switch (ret) {
69 		case 'b':
70 			if (params.perf_bias)
71 				print_wrong_arg_exit();
72 			perf_bias = atoi(optarg);
73 			if (perf_bias < 0 || perf_bias > 15) {
74 				printf(_("--perf-bias param out "
75 					 "of range [0-%d]\n"), 15);
76 				print_wrong_arg_exit();
77 			}
78 			params.perf_bias = 1;
79 			break;
80 		case 'e':
81 			if (params.epp)
82 				print_wrong_arg_exit();
83 			if (sscanf(optarg, "%29s", epp) != 1) {
84 				print_wrong_arg_exit();
85 				return -EINVAL;
86 			}
87 			params.epp = 1;
88 			break;
89 		case 'm':
90 			if (cpupower_cpu_info.vendor != X86_VENDOR_AMD)
91 				print_wrong_arg_exit();
92 			if (params.mode)
93 				print_wrong_arg_exit();
94 			if (sscanf(optarg, "%19s", mode) != 1) {
95 				print_wrong_arg_exit();
96 				return -EINVAL;
97 			}
98 			params.mode = 1;
99 			break;
100 		case 't':
101 			if (params.turbo_boost)
102 				print_wrong_arg_exit();
103 			turbo_boost = atoi(optarg);
104 			if (turbo_boost < 0 || turbo_boost > 1) {
105 				printf("--turbo-boost param out of range [0-1]\n");
106 				print_wrong_arg_exit();
107 			}
108 			params.turbo_boost = 1;
109 			break;
110 
111 
112 		default:
113 			print_wrong_arg_exit();
114 		}
115 	}
116 
117 	if (!params.params)
118 		print_wrong_arg_exit();
119 
120 	if (params.mode) {
121 		ret = cpupower_set_amd_pstate_mode(mode);
122 		if (ret)
123 			fprintf(stderr, "Error setting mode\n");
124 	}
125 
126 	if (params.turbo_boost) {
127 		ret = cpupower_set_turbo_boost(turbo_boost);
128 		if (ret)
129 			fprintf(stderr, "Error setting turbo-boost\n");
130 	}
131 
132 	/* Default is: set all CPUs */
133 	if (bitmask_isallclear(cpus_chosen))
134 		bitmask_setall(cpus_chosen);
135 
136 	/* loop over CPUs */
137 	for (cpu = bitmask_first(cpus_chosen);
138 	     cpu <= bitmask_last(cpus_chosen); cpu++) {
139 
140 		if (!bitmask_isbitset(cpus_chosen, cpu))
141 			continue;
142 
143 		if (sysfs_is_cpu_online(cpu) != 1){
144 			fprintf(stderr, _("Cannot set values on CPU %d:"), cpu);
145 			fprintf(stderr, _(" *is offline\n"));
146 			continue;
147 		}
148 
149 		if (params.perf_bias) {
150 			ret = cpupower_intel_set_perf_bias(cpu, perf_bias);
151 			if (ret) {
152 				fprintf(stderr, _("Error setting perf-bias "
153 						  "value on CPU %d\n"), cpu);
154 				break;
155 			}
156 		}
157 
158 		if (params.epp) {
159 			ret = cpupower_set_epp(cpu, epp);
160 			if (ret) {
161 				fprintf(stderr,
162 					"Error setting epp value on CPU %d\n", cpu);
163 				break;
164 			}
165 		}
166 
167 	}
168 	return ret;
169 }
170