Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pcc-cpufreq.c
Go to the documentation of this file.
1 /*
2  * pcc-cpufreq.c - Processor Clocking Control firmware cpufreq interface
3  *
4  * Copyright (C) 2009 Red Hat, Matthew Garrett <[email protected]>
5  * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
6  * Nagananda Chumbalkar <[email protected]>
7  *
8  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; version 2 of the License.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or NON
17  * INFRINGEMENT. See the GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 675 Mass Ave, Cambridge, MA 02139, USA.
22  *
23  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24  */
25 
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/smp.h>
30 #include <linux/sched.h>
31 #include <linux/cpufreq.h>
32 #include <linux/compiler.h>
33 #include <linux/slab.h>
34 
35 #include <linux/acpi.h>
36 #include <linux/io.h>
37 #include <linux/spinlock.h>
38 #include <linux/uaccess.h>
39 
40 #include <acpi/processor.h>
41 
42 #define PCC_VERSION "1.10.00"
43 #define POLL_LOOPS 300
44 
45 #define CMD_COMPLETE 0x1
46 #define CMD_GET_FREQ 0x0
47 #define CMD_SET_FREQ 0x1
48 
49 #define BUF_SZ 4
50 
59 } __attribute__ ((packed));
60 
72 } __attribute__ ((packed));
73 
74 static struct cpufreq_driver pcc_cpufreq_driver;
75 
76 struct pcc_header {
90 };
91 
92 static void __iomem *pcch_virt_addr;
93 static struct pcc_header __iomem *pcch_hdr;
94 
95 static DEFINE_SPINLOCK(pcc_lock);
96 
97 static struct acpi_generic_address doorbell;
98 
99 static u64 doorbell_preserve;
100 static u64 doorbell_write;
101 
102 static u8 OSC_UUID[16] = {0x9F, 0x2C, 0x9B, 0x63, 0x91, 0x70, 0x1f, 0x49,
103  0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46};
104 
105 struct pcc_cpu {
108 };
109 
110 static struct pcc_cpu __percpu *pcc_cpu_info;
111 
112 static int pcc_cpufreq_verify(struct cpufreq_policy *policy)
113 {
114  cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq,
115  policy->cpuinfo.max_freq);
116  return 0;
117 }
118 
119 static inline void pcc_cmd(void)
120 {
121  u64 doorbell_value;
122  int i;
123 
124  acpi_read(&doorbell_value, &doorbell);
125  acpi_write((doorbell_value & doorbell_preserve) | doorbell_write,
126  &doorbell);
127 
128  for (i = 0; i < POLL_LOOPS; i++) {
129  if (ioread16(&pcch_hdr->status) & CMD_COMPLETE)
130  break;
131  }
132 }
133 
134 static inline void pcc_clear_mapping(void)
135 {
136  if (pcch_virt_addr)
137  iounmap(pcch_virt_addr);
138  pcch_virt_addr = NULL;
139 }
140 
141 static unsigned int pcc_get_freq(unsigned int cpu)
142 {
143  struct pcc_cpu *pcc_cpu_data;
144  unsigned int curr_freq;
145  unsigned int freq_limit;
146  u16 status;
147  u32 input_buffer;
149 
150  spin_lock(&pcc_lock);
151 
152  pr_debug("get: get_freq for CPU %d\n", cpu);
153  pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
154 
155  input_buffer = 0x1;
156  iowrite32(input_buffer,
157  (pcch_virt_addr + pcc_cpu_data->input_offset));
158  iowrite16(CMD_GET_FREQ, &pcch_hdr->command);
159 
160  pcc_cmd();
161 
162  output_buffer =
163  ioread32(pcch_virt_addr + pcc_cpu_data->output_offset);
164 
165  /* Clear the input buffer - we are done with the current command */
166  memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
167 
168  status = ioread16(&pcch_hdr->status);
169  if (status != CMD_COMPLETE) {
170  pr_debug("get: FAILED: for CPU %d, status is %d\n",
171  cpu, status);
172  goto cmd_incomplete;
173  }
174  iowrite16(0, &pcch_hdr->status);
175  curr_freq = (((ioread32(&pcch_hdr->nominal) * (output_buffer & 0xff))
176  / 100) * 1000);
177 
178  pr_debug("get: SUCCESS: (virtual) output_offset for cpu %d is "
179  "0x%p, contains a value of: 0x%x. Speed is: %d MHz\n",
180  cpu, (pcch_virt_addr + pcc_cpu_data->output_offset),
181  output_buffer, curr_freq);
182 
183  freq_limit = (output_buffer >> 8) & 0xff;
184  if (freq_limit != 0xff) {
185  pr_debug("get: frequency for cpu %d is being temporarily"
186  " capped at %d\n", cpu, curr_freq);
187  }
188 
189  spin_unlock(&pcc_lock);
190  return curr_freq;
191 
192 cmd_incomplete:
193  iowrite16(0, &pcch_hdr->status);
194  spin_unlock(&pcc_lock);
195  return 0;
196 }
197 
198 static int pcc_cpufreq_target(struct cpufreq_policy *policy,
199  unsigned int target_freq,
200  unsigned int relation)
201 {
202  struct pcc_cpu *pcc_cpu_data;
203  struct cpufreq_freqs freqs;
204  u16 status;
205  u32 input_buffer;
206  int cpu;
207 
208  spin_lock(&pcc_lock);
209  cpu = policy->cpu;
210  pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
211 
212  pr_debug("target: CPU %d should go to target freq: %d "
213  "(virtual) input_offset is 0x%p\n",
214  cpu, target_freq,
215  (pcch_virt_addr + pcc_cpu_data->input_offset));
216 
217  freqs.new = target_freq;
218  freqs.cpu = cpu;
220 
221  input_buffer = 0x1 | (((target_freq * 100)
222  / (ioread32(&pcch_hdr->nominal) * 1000)) << 8);
223  iowrite32(input_buffer,
224  (pcch_virt_addr + pcc_cpu_data->input_offset));
225  iowrite16(CMD_SET_FREQ, &pcch_hdr->command);
226 
227  pcc_cmd();
228 
229  /* Clear the input buffer - we are done with the current command */
230  memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
231 
232  status = ioread16(&pcch_hdr->status);
233  if (status != CMD_COMPLETE) {
234  pr_debug("target: FAILED for cpu %d, with status: 0x%x\n",
235  cpu, status);
236  goto cmd_incomplete;
237  }
238  iowrite16(0, &pcch_hdr->status);
239 
241  pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu);
242  spin_unlock(&pcc_lock);
243 
244  return 0;
245 
246 cmd_incomplete:
247  iowrite16(0, &pcch_hdr->status);
248  spin_unlock(&pcc_lock);
249  return -EINVAL;
250 }
251 
252 static int pcc_get_offset(int cpu)
253 {
256  union acpi_object *pccp, *offset;
257  struct pcc_cpu *pcc_cpu_data;
258  struct acpi_processor *pr;
259  int ret = 0;
260 
261  pr = per_cpu(processors, cpu);
262  pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
263 
264  if (!pr)
265  return -ENODEV;
266 
267  status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer);
268  if (ACPI_FAILURE(status))
269  return -ENODEV;
270 
271  pccp = buffer.pointer;
272  if (!pccp || pccp->type != ACPI_TYPE_PACKAGE) {
273  ret = -ENODEV;
274  goto out_free;
275  };
276 
277  offset = &(pccp->package.elements[0]);
278  if (!offset || offset->type != ACPI_TYPE_INTEGER) {
279  ret = -ENODEV;
280  goto out_free;
281  }
282 
283  pcc_cpu_data->input_offset = offset->integer.value;
284 
285  offset = &(pccp->package.elements[1]);
286  if (!offset || offset->type != ACPI_TYPE_INTEGER) {
287  ret = -ENODEV;
288  goto out_free;
289  }
290 
291  pcc_cpu_data->output_offset = offset->integer.value;
292 
293  memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
294  memset_io((pcch_virt_addr + pcc_cpu_data->output_offset), 0, BUF_SZ);
295 
296  pr_debug("pcc_get_offset: for CPU %d: pcc_cpu_data "
297  "input_offset: 0x%x, pcc_cpu_data output_offset: 0x%x\n",
298  cpu, pcc_cpu_data->input_offset, pcc_cpu_data->output_offset);
299 out_free:
300  kfree(buffer.pointer);
301  return ret;
302 }
303 
304 static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
305 {
307  struct acpi_object_list input;
309  union acpi_object in_params[4];
310  union acpi_object *out_obj;
311  u32 capabilities[2];
312  u32 errors;
313  u32 supported;
314  int ret = 0;
315 
316  input.count = 4;
317  input.pointer = in_params;
318  in_params[0].type = ACPI_TYPE_BUFFER;
319  in_params[0].buffer.length = 16;
320  in_params[0].buffer.pointer = OSC_UUID;
321  in_params[1].type = ACPI_TYPE_INTEGER;
322  in_params[1].integer.value = 1;
323  in_params[2].type = ACPI_TYPE_INTEGER;
324  in_params[2].integer.value = 2;
325  in_params[3].type = ACPI_TYPE_BUFFER;
326  in_params[3].buffer.length = 8;
327  in_params[3].buffer.pointer = (u8 *)&capabilities;
328 
329  capabilities[0] = OSC_QUERY_ENABLE;
330  capabilities[1] = 0x1;
331 
332  status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
333  if (ACPI_FAILURE(status))
334  return -ENODEV;
335 
336  if (!output.length)
337  return -ENODEV;
338 
339  out_obj = output.pointer;
340  if (out_obj->type != ACPI_TYPE_BUFFER) {
341  ret = -ENODEV;
342  goto out_free;
343  }
344 
345  errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
346  if (errors) {
347  ret = -ENODEV;
348  goto out_free;
349  }
350 
351  supported = *((u32 *)(out_obj->buffer.pointer + 4));
352  if (!(supported & 0x1)) {
353  ret = -ENODEV;
354  goto out_free;
355  }
356 
357  kfree(output.pointer);
358  capabilities[0] = 0x0;
359  capabilities[1] = 0x1;
360 
361  status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
362  if (ACPI_FAILURE(status))
363  return -ENODEV;
364 
365  if (!output.length)
366  return -ENODEV;
367 
368  out_obj = output.pointer;
369  if (out_obj->type != ACPI_TYPE_BUFFER) {
370  ret = -ENODEV;
371  goto out_free;
372  }
373 
374  errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
375  if (errors) {
376  ret = -ENODEV;
377  goto out_free;
378  }
379 
380  supported = *((u32 *)(out_obj->buffer.pointer + 4));
381  if (!(supported & 0x1)) {
382  ret = -ENODEV;
383  goto out_free;
384  }
385 
386 out_free:
387  kfree(output.pointer);
388  return ret;
389 }
390 
391 static int __init pcc_cpufreq_probe(void)
392 {
394  struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
395  struct pcc_memory_resource *mem_resource;
396  struct pcc_register_resource *reg_resource;
397  union acpi_object *out_obj, *member;
398  acpi_handle handle, osc_handle, pcch_handle;
399  int ret = 0;
400 
401  status = acpi_get_handle(NULL, "\\_SB", &handle);
402  if (ACPI_FAILURE(status))
403  return -ENODEV;
404 
405  status = acpi_get_handle(handle, "PCCH", &pcch_handle);
406  if (ACPI_FAILURE(status))
407  return -ENODEV;
408 
409  status = acpi_get_handle(handle, "_OSC", &osc_handle);
410  if (ACPI_SUCCESS(status)) {
411  ret = pcc_cpufreq_do_osc(&osc_handle);
412  if (ret)
413  pr_debug("probe: _OSC evaluation did not succeed\n");
414  /* Firmware's use of _OSC is optional */
415  ret = 0;
416  }
417 
418  status = acpi_evaluate_object(handle, "PCCH", NULL, &output);
419  if (ACPI_FAILURE(status))
420  return -ENODEV;
421 
422  out_obj = output.pointer;
423  if (out_obj->type != ACPI_TYPE_PACKAGE) {
424  ret = -ENODEV;
425  goto out_free;
426  }
427 
428  member = &out_obj->package.elements[0];
429  if (member->type != ACPI_TYPE_BUFFER) {
430  ret = -ENODEV;
431  goto out_free;
432  }
433 
434  mem_resource = (struct pcc_memory_resource *)member->buffer.pointer;
435 
436  pr_debug("probe: mem_resource descriptor: 0x%x,"
437  " length: %d, space_id: %d, resource_usage: %d,"
438  " type_specific: %d, granularity: 0x%llx,"
439  " minimum: 0x%llx, maximum: 0x%llx,"
440  " translation_offset: 0x%llx, address_length: 0x%llx\n",
441  mem_resource->descriptor, mem_resource->length,
442  mem_resource->space_id, mem_resource->resource_usage,
443  mem_resource->type_specific, mem_resource->granularity,
444  mem_resource->minimum, mem_resource->maximum,
445  mem_resource->translation_offset,
446  mem_resource->address_length);
447 
448  if (mem_resource->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
449  ret = -ENODEV;
450  goto out_free;
451  }
452 
453  pcch_virt_addr = ioremap_nocache(mem_resource->minimum,
454  mem_resource->address_length);
455  if (pcch_virt_addr == NULL) {
456  pr_debug("probe: could not map shared mem region\n");
457  ret = -ENOMEM;
458  goto out_free;
459  }
460  pcch_hdr = pcch_virt_addr;
461 
462  pr_debug("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr);
463  pr_debug("probe: PCCH header is at physical address: 0x%llx,"
464  " signature: 0x%x, length: %d bytes, major: %d, minor: %d,"
465  " supported features: 0x%x, command field: 0x%x,"
466  " status field: 0x%x, nominal latency: %d us\n",
467  mem_resource->minimum, ioread32(&pcch_hdr->signature),
468  ioread16(&pcch_hdr->length), ioread8(&pcch_hdr->major),
469  ioread8(&pcch_hdr->minor), ioread32(&pcch_hdr->features),
470  ioread16(&pcch_hdr->command), ioread16(&pcch_hdr->status),
471  ioread32(&pcch_hdr->latency));
472 
473  pr_debug("probe: min time between commands: %d us,"
474  " max time between commands: %d us,"
475  " nominal CPU frequency: %d MHz,"
476  " minimum CPU frequency: %d MHz,"
477  " minimum CPU frequency without throttling: %d MHz\n",
478  ioread32(&pcch_hdr->minimum_time),
479  ioread32(&pcch_hdr->maximum_time),
480  ioread32(&pcch_hdr->nominal),
481  ioread32(&pcch_hdr->throttled_frequency),
482  ioread32(&pcch_hdr->minimum_frequency));
483 
484  member = &out_obj->package.elements[1];
485  if (member->type != ACPI_TYPE_BUFFER) {
486  ret = -ENODEV;
487  goto pcch_free;
488  }
489 
490  reg_resource = (struct pcc_register_resource *)member->buffer.pointer;
491 
492  doorbell.space_id = reg_resource->space_id;
493  doorbell.bit_width = reg_resource->bit_width;
494  doorbell.bit_offset = reg_resource->bit_offset;
495  doorbell.access_width = 64;
496  doorbell.address = reg_resource->address;
497 
498  pr_debug("probe: doorbell: space_id is %d, bit_width is %d, "
499  "bit_offset is %d, access_width is %d, address is 0x%llx\n",
500  doorbell.space_id, doorbell.bit_width, doorbell.bit_offset,
501  doorbell.access_width, reg_resource->address);
502 
503  member = &out_obj->package.elements[2];
504  if (member->type != ACPI_TYPE_INTEGER) {
505  ret = -ENODEV;
506  goto pcch_free;
507  }
508 
509  doorbell_preserve = member->integer.value;
510 
511  member = &out_obj->package.elements[3];
512  if (member->type != ACPI_TYPE_INTEGER) {
513  ret = -ENODEV;
514  goto pcch_free;
515  }
516 
517  doorbell_write = member->integer.value;
518 
519  pr_debug("probe: doorbell_preserve: 0x%llx,"
520  " doorbell_write: 0x%llx\n",
521  doorbell_preserve, doorbell_write);
522 
523  pcc_cpu_info = alloc_percpu(struct pcc_cpu);
524  if (!pcc_cpu_info) {
525  ret = -ENOMEM;
526  goto pcch_free;
527  }
528 
529  printk(KERN_DEBUG "pcc-cpufreq: (v%s) driver loaded with frequency"
530  " limits: %d MHz, %d MHz\n", PCC_VERSION,
531  ioread32(&pcch_hdr->minimum_frequency),
532  ioread32(&pcch_hdr->nominal));
533  kfree(output.pointer);
534  return ret;
535 pcch_free:
536  pcc_clear_mapping();
537 out_free:
538  kfree(output.pointer);
539  return ret;
540 }
541 
542 static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
543 {
544  unsigned int cpu = policy->cpu;
545  unsigned int result = 0;
546 
547  if (!pcch_virt_addr) {
548  result = -1;
549  goto out;
550  }
551 
552  result = pcc_get_offset(cpu);
553  if (result) {
554  pr_debug("init: PCCP evaluation failed\n");
555  goto out;
556  }
557 
558  policy->max = policy->cpuinfo.max_freq =
559  ioread32(&pcch_hdr->nominal) * 1000;
560  policy->min = policy->cpuinfo.min_freq =
561  ioread32(&pcch_hdr->minimum_frequency) * 1000;
562  policy->cur = pcc_get_freq(cpu);
563 
564  if (!policy->cur) {
565  pr_debug("init: Unable to get current CPU frequency\n");
566  result = -EINVAL;
567  goto out;
568  }
569 
570  pr_debug("init: policy->max is %d, policy->min is %d\n",
571  policy->max, policy->min);
572 out:
573  return result;
574 }
575 
576 static int pcc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
577 {
578  return 0;
579 }
580 
581 static struct cpufreq_driver pcc_cpufreq_driver = {
582  .flags = CPUFREQ_CONST_LOOPS,
583  .get = pcc_get_freq,
584  .verify = pcc_cpufreq_verify,
585  .target = pcc_cpufreq_target,
586  .init = pcc_cpufreq_cpu_init,
587  .exit = pcc_cpufreq_cpu_exit,
588  .name = "pcc-cpufreq",
589  .owner = THIS_MODULE,
590 };
591 
592 static int __init pcc_cpufreq_init(void)
593 {
594  int ret;
595 
596  if (acpi_disabled)
597  return 0;
598 
599  ret = pcc_cpufreq_probe();
600  if (ret) {
601  pr_debug("pcc_cpufreq_init: PCCH evaluation failed\n");
602  return ret;
603  }
604 
605  ret = cpufreq_register_driver(&pcc_cpufreq_driver);
606 
607  return ret;
608 }
609 
610 static void __exit pcc_cpufreq_exit(void)
611 {
612  cpufreq_unregister_driver(&pcc_cpufreq_driver);
613 
614  pcc_clear_mapping();
615 
616  free_percpu(pcc_cpu_info);
617 }
618 
619 MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar");
621 MODULE_DESCRIPTION("Processor Clocking Control interface driver");
622 MODULE_LICENSE("GPL");
623 
624 late_initcall(pcc_cpufreq_init);
625 module_exit(pcc_cpufreq_exit);