1 /*
2  * processor_throttling.c - Throttling submodule of the ACPI processor driver
3  *
4  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6  *  Copyright (C) 2004       Dominik Brodowski <linux@brodo.de>
7  *  Copyright (C) 2004  Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
8  *  			- Added processor hotplug support
9  *
10  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11  *
12  *  This program is free software; you can redistribute it and/or modify
13  *  it under the terms of the GNU General Public License as published by
14  *  the Free Software Foundation; either version 2 of the License, or (at
15  *  your option) any later version.
16  *
17  *  This program is distributed in the hope that it will be useful, but
18  *  WITHOUT ANY WARRANTY; without even the implied warranty of
19  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  *  General Public License for more details.
21  *
22  *  You should have received a copy of the GNU General Public License along
23  *  with this program; if not, write to the Free Software Foundation, Inc.,
24  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25  *
26  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27  */
28 
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/cpufreq.h>
33 #include <linux/proc_fs.h>
34 #include <linux/seq_file.h>
35 
36 #include <asm/io.h>
37 #include <asm/uaccess.h>
38 
39 #include <acpi/acpi_bus.h>
40 #include <acpi/processor.h>
41 
42 #define ACPI_PROCESSOR_COMPONENT        0x01000000
43 #define ACPI_PROCESSOR_CLASS            "processor"
44 #define _COMPONENT              ACPI_PROCESSOR_COMPONENT
45 ACPI_MODULE_NAME("processor_throttling");
46 
47 /* --------------------------------------------------------------------------
48                               Throttling Control
49    -------------------------------------------------------------------------- */
50 static int acpi_processor_get_throttling(struct acpi_processor *pr)
51 {
52 	int state = 0;
53 	u32 value = 0;
54 	u32 duty_mask = 0;
55 	u32 duty_value = 0;
56 
57 
58 	if (!pr)
59 		return -EINVAL;
60 
61 	if (!pr->flags.throttling)
62 		return -ENODEV;
63 
64 	pr->throttling.state = 0;
65 
66 	duty_mask = pr->throttling.state_count - 1;
67 
68 	duty_mask <<= pr->throttling.duty_offset;
69 
70 	local_irq_disable();
71 
72 	value = inl(pr->throttling.address);
73 
74 	/*
75 	 * Compute the current throttling state when throttling is enabled
76 	 * (bit 4 is on).
77 	 */
78 	if (value & 0x10) {
79 		duty_value = value & duty_mask;
80 		duty_value >>= pr->throttling.duty_offset;
81 
82 		if (duty_value)
83 			state = pr->throttling.state_count - duty_value;
84 	}
85 
86 	pr->throttling.state = state;
87 
88 	local_irq_enable();
89 
90 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
91 			  "Throttling state is T%d (%d%% throttling applied)\n",
92 			  state, pr->throttling.states[state].performance));
93 
94 	return 0;
95 }
96 
97 int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
98 {
99 	u32 value = 0;
100 	u32 duty_mask = 0;
101 	u32 duty_value = 0;
102 
103 
104 	if (!pr)
105 		return -EINVAL;
106 
107 	if ((state < 0) || (state > (pr->throttling.state_count - 1)))
108 		return -EINVAL;
109 
110 	if (!pr->flags.throttling)
111 		return -ENODEV;
112 
113 	if (state == pr->throttling.state)
114 		return 0;
115 
116 	/*
117 	 * Calculate the duty_value and duty_mask.
118 	 */
119 	if (state) {
120 		duty_value = pr->throttling.state_count - state;
121 
122 		duty_value <<= pr->throttling.duty_offset;
123 
124 		/* Used to clear all duty_value bits */
125 		duty_mask = pr->throttling.state_count - 1;
126 
127 		duty_mask <<= acpi_gbl_FADT.duty_offset;
128 		duty_mask = ~duty_mask;
129 	}
130 
131 	local_irq_disable();
132 
133 	/*
134 	 * Disable throttling by writing a 0 to bit 4.  Note that we must
135 	 * turn it off before you can change the duty_value.
136 	 */
137 	value = inl(pr->throttling.address);
138 	if (value & 0x10) {
139 		value &= 0xFFFFFFEF;
140 		outl(value, pr->throttling.address);
141 	}
142 
143 	/*
144 	 * Write the new duty_value and then enable throttling.  Note
145 	 * that a state value of 0 leaves throttling disabled.
146 	 */
147 	if (state) {
148 		value &= duty_mask;
149 		value |= duty_value;
150 		outl(value, pr->throttling.address);
151 
152 		value |= 0x00000010;
153 		outl(value, pr->throttling.address);
154 	}
155 
156 	pr->throttling.state = state;
157 
158 	local_irq_enable();
159 
160 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
161 			  "Throttling state set to T%d (%d%%)\n", state,
162 			  (pr->throttling.states[state].performance ? pr->
163 			   throttling.states[state].performance / 10 : 0)));
164 
165 	return 0;
166 }
167 
168 int acpi_processor_get_throttling_info(struct acpi_processor *pr)
169 {
170 	int result = 0;
171 	int step = 0;
172 	int i = 0;
173 
174 
175 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
176 			  "pblk_address[0x%08x] duty_offset[%d] duty_width[%d]\n",
177 			  pr->throttling.address,
178 			  pr->throttling.duty_offset,
179 			  pr->throttling.duty_width));
180 
181 	if (!pr)
182 		return -EINVAL;
183 
184 	/* TBD: Support ACPI 2.0 objects */
185 
186 	if (!pr->throttling.address) {
187 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling register\n"));
188 		return 0;
189 	} else if (!pr->throttling.duty_width) {
190 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No throttling states\n"));
191 		return 0;
192 	}
193 	/* TBD: Support duty_cycle values that span bit 4. */
194 	else if ((pr->throttling.duty_offset + pr->throttling.duty_width) > 4) {
195 		printk(KERN_WARNING PREFIX "duty_cycle spans bit 4\n");
196 		return 0;
197 	}
198 
199 	/*
200 	 * PIIX4 Errata: We don't support throttling on the original PIIX4.
201 	 * This shouldn't be an issue as few (if any) mobile systems ever
202 	 * used this part.
203 	 */
204 	if (errata.piix4.throttle) {
205 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
206 				  "Throttling not supported on PIIX4 A- or B-step\n"));
207 		return 0;
208 	}
209 
210 	pr->throttling.state_count = 1 << acpi_gbl_FADT.duty_width;
211 
212 	/*
213 	 * Compute state values. Note that throttling displays a linear power/
214 	 * performance relationship (at 50% performance the CPU will consume
215 	 * 50% power).  Values are in 1/10th of a percent to preserve accuracy.
216 	 */
217 
218 	step = (1000 / pr->throttling.state_count);
219 
220 	for (i = 0; i < pr->throttling.state_count; i++) {
221 		pr->throttling.states[i].performance = step * i;
222 		pr->throttling.states[i].power = step * i;
223 	}
224 
225 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d throttling states\n",
226 			  pr->throttling.state_count));
227 
228 	pr->flags.throttling = 1;
229 
230 	/*
231 	 * Disable throttling (if enabled).  We'll let subsequent policy (e.g.
232 	 * thermal) decide to lower performance if it so chooses, but for now
233 	 * we'll crank up the speed.
234 	 */
235 
236 	result = acpi_processor_get_throttling(pr);
237 	if (result)
238 		goto end;
239 
240 	if (pr->throttling.state) {
241 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
242 				  "Disabling throttling (was T%d)\n",
243 				  pr->throttling.state));
244 		result = acpi_processor_set_throttling(pr, 0);
245 		if (result)
246 			goto end;
247 	}
248 
249       end:
250 	if (result)
251 		pr->flags.throttling = 0;
252 
253 	return result;
254 }
255 
256 /* proc interface */
257 
258 static int acpi_processor_throttling_seq_show(struct seq_file *seq,
259 					      void *offset)
260 {
261 	struct acpi_processor *pr = seq->private;
262 	int i = 0;
263 	int result = 0;
264 
265 
266 	if (!pr)
267 		goto end;
268 
269 	if (!(pr->throttling.state_count > 0)) {
270 		seq_puts(seq, "<not supported>\n");
271 		goto end;
272 	}
273 
274 	result = acpi_processor_get_throttling(pr);
275 
276 	if (result) {
277 		seq_puts(seq,
278 			 "Could not determine current throttling state.\n");
279 		goto end;
280 	}
281 
282 	seq_printf(seq, "state count:             %d\n"
283 		   "active state:            T%d\n",
284 		   pr->throttling.state_count, pr->throttling.state);
285 
286 	seq_puts(seq, "states:\n");
287 	for (i = 0; i < pr->throttling.state_count; i++)
288 		seq_printf(seq, "   %cT%d:                  %02d%%\n",
289 			   (i == pr->throttling.state ? '*' : ' '), i,
290 			   (pr->throttling.states[i].performance ? pr->
291 			    throttling.states[i].performance / 10 : 0));
292 
293       end:
294 	return 0;
295 }
296 
297 static int acpi_processor_throttling_open_fs(struct inode *inode,
298 					     struct file *file)
299 {
300 	return single_open(file, acpi_processor_throttling_seq_show,
301 			   PDE(inode)->data);
302 }
303 
304 static ssize_t acpi_processor_write_throttling(struct file * file,
305 					       const char __user * buffer,
306 					       size_t count, loff_t * data)
307 {
308 	int result = 0;
309 	struct seq_file *m = file->private_data;
310 	struct acpi_processor *pr = m->private;
311 	char state_string[12] = { '\0' };
312 
313 
314 	if (!pr || (count > sizeof(state_string) - 1))
315 		return -EINVAL;
316 
317 	if (copy_from_user(state_string, buffer, count))
318 		return -EFAULT;
319 
320 	state_string[count] = '\0';
321 
322 	result = acpi_processor_set_throttling(pr,
323 					       simple_strtoul(state_string,
324 							      NULL, 0));
325 	if (result)
326 		return result;
327 
328 	return count;
329 }
330 
331 struct file_operations acpi_processor_throttling_fops = {
332 	.open = acpi_processor_throttling_open_fs,
333 	.read = seq_read,
334 	.write = acpi_processor_write_throttling,
335 	.llseek = seq_lseek,
336 	.release = single_release,
337 };
338