0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026 #include <linux/kernel.h>
0027 #include <linux/module.h>
0028 #include <linux/init.h>
0029 #include <linux/smp.h>
0030 #include <linux/sched.h>
0031 #include <linux/cpufreq.h>
0032 #include <linux/compiler.h>
0033 #include <linux/slab.h>
0034
0035 #include <linux/acpi.h>
0036 #include <linux/io.h>
0037 #include <linux/spinlock.h>
0038 #include <linux/uaccess.h>
0039
0040 #include <acpi/processor.h>
0041
0042 #define PCC_VERSION "1.10.00"
0043 #define POLL_LOOPS 300
0044
0045 #define CMD_COMPLETE 0x1
0046 #define CMD_GET_FREQ 0x0
0047 #define CMD_SET_FREQ 0x1
0048
0049 #define BUF_SZ 4
0050
0051 struct pcc_register_resource {
0052 u8 descriptor;
0053 u16 length;
0054 u8 space_id;
0055 u8 bit_width;
0056 u8 bit_offset;
0057 u8 access_size;
0058 u64 address;
0059 } __attribute__ ((packed));
0060
0061 struct pcc_memory_resource {
0062 u8 descriptor;
0063 u16 length;
0064 u8 space_id;
0065 u8 resource_usage;
0066 u8 type_specific;
0067 u64 granularity;
0068 u64 minimum;
0069 u64 maximum;
0070 u64 translation_offset;
0071 u64 address_length;
0072 } __attribute__ ((packed));
0073
0074 static struct cpufreq_driver pcc_cpufreq_driver;
0075
0076 struct pcc_header {
0077 u32 signature;
0078 u16 length;
0079 u8 major;
0080 u8 minor;
0081 u32 features;
0082 u16 command;
0083 u16 status;
0084 u32 latency;
0085 u32 minimum_time;
0086 u32 maximum_time;
0087 u32 nominal;
0088 u32 throttled_frequency;
0089 u32 minimum_frequency;
0090 };
0091
0092 static void __iomem *pcch_virt_addr;
0093 static struct pcc_header __iomem *pcch_hdr;
0094
0095 static DEFINE_SPINLOCK(pcc_lock);
0096
0097 static struct acpi_generic_address doorbell;
0098
0099 static u64 doorbell_preserve;
0100 static u64 doorbell_write;
0101
0102 static u8 OSC_UUID[16] = {0x9F, 0x2C, 0x9B, 0x63, 0x91, 0x70, 0x1f, 0x49,
0103 0xBB, 0x4F, 0xA5, 0x98, 0x2F, 0xA1, 0xB5, 0x46};
0104
0105 struct pcc_cpu {
0106 u32 input_offset;
0107 u32 output_offset;
0108 };
0109
0110 static struct pcc_cpu __percpu *pcc_cpu_info;
0111
0112 static int pcc_cpufreq_verify(struct cpufreq_policy_data *policy)
0113 {
0114 cpufreq_verify_within_cpu_limits(policy);
0115 return 0;
0116 }
0117
0118 static inline void pcc_cmd(void)
0119 {
0120 u64 doorbell_value;
0121 int i;
0122
0123 acpi_read(&doorbell_value, &doorbell);
0124 acpi_write((doorbell_value & doorbell_preserve) | doorbell_write,
0125 &doorbell);
0126
0127 for (i = 0; i < POLL_LOOPS; i++) {
0128 if (ioread16(&pcch_hdr->status) & CMD_COMPLETE)
0129 break;
0130 }
0131 }
0132
0133 static inline void pcc_clear_mapping(void)
0134 {
0135 if (pcch_virt_addr)
0136 iounmap(pcch_virt_addr);
0137 pcch_virt_addr = NULL;
0138 }
0139
0140 static unsigned int pcc_get_freq(unsigned int cpu)
0141 {
0142 struct pcc_cpu *pcc_cpu_data;
0143 unsigned int curr_freq;
0144 unsigned int freq_limit;
0145 u16 status;
0146 u32 input_buffer;
0147 u32 output_buffer;
0148
0149 spin_lock(&pcc_lock);
0150
0151 pr_debug("get: get_freq for CPU %d\n", cpu);
0152 pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
0153
0154 input_buffer = 0x1;
0155 iowrite32(input_buffer,
0156 (pcch_virt_addr + pcc_cpu_data->input_offset));
0157 iowrite16(CMD_GET_FREQ, &pcch_hdr->command);
0158
0159 pcc_cmd();
0160
0161 output_buffer =
0162 ioread32(pcch_virt_addr + pcc_cpu_data->output_offset);
0163
0164
0165 memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
0166
0167 status = ioread16(&pcch_hdr->status);
0168 if (status != CMD_COMPLETE) {
0169 pr_debug("get: FAILED: for CPU %d, status is %d\n",
0170 cpu, status);
0171 goto cmd_incomplete;
0172 }
0173 iowrite16(0, &pcch_hdr->status);
0174 curr_freq = (((ioread32(&pcch_hdr->nominal) * (output_buffer & 0xff))
0175 / 100) * 1000);
0176
0177 pr_debug("get: SUCCESS: (virtual) output_offset for cpu %d is "
0178 "0x%p, contains a value of: 0x%x. Speed is: %d MHz\n",
0179 cpu, (pcch_virt_addr + pcc_cpu_data->output_offset),
0180 output_buffer, curr_freq);
0181
0182 freq_limit = (output_buffer >> 8) & 0xff;
0183 if (freq_limit != 0xff) {
0184 pr_debug("get: frequency for cpu %d is being temporarily"
0185 " capped at %d\n", cpu, curr_freq);
0186 }
0187
0188 spin_unlock(&pcc_lock);
0189 return curr_freq;
0190
0191 cmd_incomplete:
0192 iowrite16(0, &pcch_hdr->status);
0193 spin_unlock(&pcc_lock);
0194 return 0;
0195 }
0196
0197 static int pcc_cpufreq_target(struct cpufreq_policy *policy,
0198 unsigned int target_freq,
0199 unsigned int relation)
0200 {
0201 struct pcc_cpu *pcc_cpu_data;
0202 struct cpufreq_freqs freqs;
0203 u16 status;
0204 u32 input_buffer;
0205 int cpu;
0206
0207 cpu = policy->cpu;
0208 pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
0209
0210 pr_debug("target: CPU %d should go to target freq: %d "
0211 "(virtual) input_offset is 0x%p\n",
0212 cpu, target_freq,
0213 (pcch_virt_addr + pcc_cpu_data->input_offset));
0214
0215 freqs.old = policy->cur;
0216 freqs.new = target_freq;
0217 cpufreq_freq_transition_begin(policy, &freqs);
0218 spin_lock(&pcc_lock);
0219
0220 input_buffer = 0x1 | (((target_freq * 100)
0221 / (ioread32(&pcch_hdr->nominal) * 1000)) << 8);
0222 iowrite32(input_buffer,
0223 (pcch_virt_addr + pcc_cpu_data->input_offset));
0224 iowrite16(CMD_SET_FREQ, &pcch_hdr->command);
0225
0226 pcc_cmd();
0227
0228
0229 memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
0230
0231 status = ioread16(&pcch_hdr->status);
0232 iowrite16(0, &pcch_hdr->status);
0233
0234 cpufreq_freq_transition_end(policy, &freqs, status != CMD_COMPLETE);
0235 spin_unlock(&pcc_lock);
0236
0237 if (status != CMD_COMPLETE) {
0238 pr_debug("target: FAILED for cpu %d, with status: 0x%x\n",
0239 cpu, status);
0240 return -EINVAL;
0241 }
0242
0243 pr_debug("target: was SUCCESSFUL for cpu %d\n", cpu);
0244
0245 return 0;
0246 }
0247
0248 static int pcc_get_offset(int cpu)
0249 {
0250 acpi_status status;
0251 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
0252 union acpi_object *pccp, *offset;
0253 struct pcc_cpu *pcc_cpu_data;
0254 struct acpi_processor *pr;
0255 int ret = 0;
0256
0257 pr = per_cpu(processors, cpu);
0258 pcc_cpu_data = per_cpu_ptr(pcc_cpu_info, cpu);
0259
0260 if (!pr)
0261 return -ENODEV;
0262
0263 status = acpi_evaluate_object(pr->handle, "PCCP", NULL, &buffer);
0264 if (ACPI_FAILURE(status))
0265 return -ENODEV;
0266
0267 pccp = buffer.pointer;
0268 if (!pccp || pccp->type != ACPI_TYPE_PACKAGE) {
0269 ret = -ENODEV;
0270 goto out_free;
0271 }
0272
0273 offset = &(pccp->package.elements[0]);
0274 if (!offset || offset->type != ACPI_TYPE_INTEGER) {
0275 ret = -ENODEV;
0276 goto out_free;
0277 }
0278
0279 pcc_cpu_data->input_offset = offset->integer.value;
0280
0281 offset = &(pccp->package.elements[1]);
0282 if (!offset || offset->type != ACPI_TYPE_INTEGER) {
0283 ret = -ENODEV;
0284 goto out_free;
0285 }
0286
0287 pcc_cpu_data->output_offset = offset->integer.value;
0288
0289 memset_io((pcch_virt_addr + pcc_cpu_data->input_offset), 0, BUF_SZ);
0290 memset_io((pcch_virt_addr + pcc_cpu_data->output_offset), 0, BUF_SZ);
0291
0292 pr_debug("pcc_get_offset: for CPU %d: pcc_cpu_data "
0293 "input_offset: 0x%x, pcc_cpu_data output_offset: 0x%x\n",
0294 cpu, pcc_cpu_data->input_offset, pcc_cpu_data->output_offset);
0295 out_free:
0296 kfree(buffer.pointer);
0297 return ret;
0298 }
0299
0300 static int __init pcc_cpufreq_do_osc(acpi_handle *handle)
0301 {
0302 acpi_status status;
0303 struct acpi_object_list input;
0304 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
0305 union acpi_object in_params[4];
0306 union acpi_object *out_obj;
0307 u32 capabilities[2];
0308 u32 errors;
0309 u32 supported;
0310 int ret = 0;
0311
0312 input.count = 4;
0313 input.pointer = in_params;
0314 in_params[0].type = ACPI_TYPE_BUFFER;
0315 in_params[0].buffer.length = 16;
0316 in_params[0].buffer.pointer = OSC_UUID;
0317 in_params[1].type = ACPI_TYPE_INTEGER;
0318 in_params[1].integer.value = 1;
0319 in_params[2].type = ACPI_TYPE_INTEGER;
0320 in_params[2].integer.value = 2;
0321 in_params[3].type = ACPI_TYPE_BUFFER;
0322 in_params[3].buffer.length = 8;
0323 in_params[3].buffer.pointer = (u8 *)&capabilities;
0324
0325 capabilities[0] = OSC_QUERY_ENABLE;
0326 capabilities[1] = 0x1;
0327
0328 status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
0329 if (ACPI_FAILURE(status))
0330 return -ENODEV;
0331
0332 if (!output.length)
0333 return -ENODEV;
0334
0335 out_obj = output.pointer;
0336 if (out_obj->type != ACPI_TYPE_BUFFER) {
0337 ret = -ENODEV;
0338 goto out_free;
0339 }
0340
0341 errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
0342 if (errors) {
0343 ret = -ENODEV;
0344 goto out_free;
0345 }
0346
0347 supported = *((u32 *)(out_obj->buffer.pointer + 4));
0348 if (!(supported & 0x1)) {
0349 ret = -ENODEV;
0350 goto out_free;
0351 }
0352
0353 kfree(output.pointer);
0354 capabilities[0] = 0x0;
0355 capabilities[1] = 0x1;
0356
0357 status = acpi_evaluate_object(*handle, "_OSC", &input, &output);
0358 if (ACPI_FAILURE(status))
0359 return -ENODEV;
0360
0361 if (!output.length)
0362 return -ENODEV;
0363
0364 out_obj = output.pointer;
0365 if (out_obj->type != ACPI_TYPE_BUFFER) {
0366 ret = -ENODEV;
0367 goto out_free;
0368 }
0369
0370 errors = *((u32 *)out_obj->buffer.pointer) & ~(1 << 0);
0371 if (errors) {
0372 ret = -ENODEV;
0373 goto out_free;
0374 }
0375
0376 supported = *((u32 *)(out_obj->buffer.pointer + 4));
0377 if (!(supported & 0x1)) {
0378 ret = -ENODEV;
0379 goto out_free;
0380 }
0381
0382 out_free:
0383 kfree(output.pointer);
0384 return ret;
0385 }
0386
0387 static int __init pcc_cpufreq_probe(void)
0388 {
0389 acpi_status status;
0390 struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL};
0391 struct pcc_memory_resource *mem_resource;
0392 struct pcc_register_resource *reg_resource;
0393 union acpi_object *out_obj, *member;
0394 acpi_handle handle, osc_handle;
0395 int ret = 0;
0396
0397 status = acpi_get_handle(NULL, "\\_SB", &handle);
0398 if (ACPI_FAILURE(status))
0399 return -ENODEV;
0400
0401 if (!acpi_has_method(handle, "PCCH"))
0402 return -ENODEV;
0403
0404 status = acpi_get_handle(handle, "_OSC", &osc_handle);
0405 if (ACPI_SUCCESS(status)) {
0406 ret = pcc_cpufreq_do_osc(&osc_handle);
0407 if (ret)
0408 pr_debug("probe: _OSC evaluation did not succeed\n");
0409
0410 ret = 0;
0411 }
0412
0413 status = acpi_evaluate_object(handle, "PCCH", NULL, &output);
0414 if (ACPI_FAILURE(status))
0415 return -ENODEV;
0416
0417 out_obj = output.pointer;
0418 if (out_obj->type != ACPI_TYPE_PACKAGE) {
0419 ret = -ENODEV;
0420 goto out_free;
0421 }
0422
0423 member = &out_obj->package.elements[0];
0424 if (member->type != ACPI_TYPE_BUFFER) {
0425 ret = -ENODEV;
0426 goto out_free;
0427 }
0428
0429 mem_resource = (struct pcc_memory_resource *)member->buffer.pointer;
0430
0431 pr_debug("probe: mem_resource descriptor: 0x%x,"
0432 " length: %d, space_id: %d, resource_usage: %d,"
0433 " type_specific: %d, granularity: 0x%llx,"
0434 " minimum: 0x%llx, maximum: 0x%llx,"
0435 " translation_offset: 0x%llx, address_length: 0x%llx\n",
0436 mem_resource->descriptor, mem_resource->length,
0437 mem_resource->space_id, mem_resource->resource_usage,
0438 mem_resource->type_specific, mem_resource->granularity,
0439 mem_resource->minimum, mem_resource->maximum,
0440 mem_resource->translation_offset,
0441 mem_resource->address_length);
0442
0443 if (mem_resource->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) {
0444 ret = -ENODEV;
0445 goto out_free;
0446 }
0447
0448 pcch_virt_addr = ioremap(mem_resource->minimum,
0449 mem_resource->address_length);
0450 if (pcch_virt_addr == NULL) {
0451 pr_debug("probe: could not map shared mem region\n");
0452 ret = -ENOMEM;
0453 goto out_free;
0454 }
0455 pcch_hdr = pcch_virt_addr;
0456
0457 pr_debug("probe: PCCH header (virtual) addr: 0x%p\n", pcch_hdr);
0458 pr_debug("probe: PCCH header is at physical address: 0x%llx,"
0459 " signature: 0x%x, length: %d bytes, major: %d, minor: %d,"
0460 " supported features: 0x%x, command field: 0x%x,"
0461 " status field: 0x%x, nominal latency: %d us\n",
0462 mem_resource->minimum, ioread32(&pcch_hdr->signature),
0463 ioread16(&pcch_hdr->length), ioread8(&pcch_hdr->major),
0464 ioread8(&pcch_hdr->minor), ioread32(&pcch_hdr->features),
0465 ioread16(&pcch_hdr->command), ioread16(&pcch_hdr->status),
0466 ioread32(&pcch_hdr->latency));
0467
0468 pr_debug("probe: min time between commands: %d us,"
0469 " max time between commands: %d us,"
0470 " nominal CPU frequency: %d MHz,"
0471 " minimum CPU frequency: %d MHz,"
0472 " minimum CPU frequency without throttling: %d MHz\n",
0473 ioread32(&pcch_hdr->minimum_time),
0474 ioread32(&pcch_hdr->maximum_time),
0475 ioread32(&pcch_hdr->nominal),
0476 ioread32(&pcch_hdr->throttled_frequency),
0477 ioread32(&pcch_hdr->minimum_frequency));
0478
0479 member = &out_obj->package.elements[1];
0480 if (member->type != ACPI_TYPE_BUFFER) {
0481 ret = -ENODEV;
0482 goto pcch_free;
0483 }
0484
0485 reg_resource = (struct pcc_register_resource *)member->buffer.pointer;
0486
0487 doorbell.space_id = reg_resource->space_id;
0488 doorbell.bit_width = reg_resource->bit_width;
0489 doorbell.bit_offset = reg_resource->bit_offset;
0490 doorbell.access_width = 4;
0491 doorbell.address = reg_resource->address;
0492
0493 pr_debug("probe: doorbell: space_id is %d, bit_width is %d, "
0494 "bit_offset is %d, access_width is %d, address is 0x%llx\n",
0495 doorbell.space_id, doorbell.bit_width, doorbell.bit_offset,
0496 doorbell.access_width, reg_resource->address);
0497
0498 member = &out_obj->package.elements[2];
0499 if (member->type != ACPI_TYPE_INTEGER) {
0500 ret = -ENODEV;
0501 goto pcch_free;
0502 }
0503
0504 doorbell_preserve = member->integer.value;
0505
0506 member = &out_obj->package.elements[3];
0507 if (member->type != ACPI_TYPE_INTEGER) {
0508 ret = -ENODEV;
0509 goto pcch_free;
0510 }
0511
0512 doorbell_write = member->integer.value;
0513
0514 pr_debug("probe: doorbell_preserve: 0x%llx,"
0515 " doorbell_write: 0x%llx\n",
0516 doorbell_preserve, doorbell_write);
0517
0518 pcc_cpu_info = alloc_percpu(struct pcc_cpu);
0519 if (!pcc_cpu_info) {
0520 ret = -ENOMEM;
0521 goto pcch_free;
0522 }
0523
0524 printk(KERN_DEBUG "pcc-cpufreq: (v%s) driver loaded with frequency"
0525 " limits: %d MHz, %d MHz\n", PCC_VERSION,
0526 ioread32(&pcch_hdr->minimum_frequency),
0527 ioread32(&pcch_hdr->nominal));
0528 kfree(output.pointer);
0529 return ret;
0530 pcch_free:
0531 pcc_clear_mapping();
0532 out_free:
0533 kfree(output.pointer);
0534 return ret;
0535 }
0536
0537 static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
0538 {
0539 unsigned int cpu = policy->cpu;
0540 unsigned int result = 0;
0541
0542 if (!pcch_virt_addr) {
0543 result = -1;
0544 goto out;
0545 }
0546
0547 result = pcc_get_offset(cpu);
0548 if (result) {
0549 pr_debug("init: PCCP evaluation failed\n");
0550 goto out;
0551 }
0552
0553 policy->max = policy->cpuinfo.max_freq =
0554 ioread32(&pcch_hdr->nominal) * 1000;
0555 policy->min = policy->cpuinfo.min_freq =
0556 ioread32(&pcch_hdr->minimum_frequency) * 1000;
0557
0558 pr_debug("init: policy->max is %d, policy->min is %d\n",
0559 policy->max, policy->min);
0560 out:
0561 return result;
0562 }
0563
0564 static int pcc_cpufreq_cpu_exit(struct cpufreq_policy *policy)
0565 {
0566 return 0;
0567 }
0568
0569 static struct cpufreq_driver pcc_cpufreq_driver = {
0570 .flags = CPUFREQ_CONST_LOOPS,
0571 .get = pcc_get_freq,
0572 .verify = pcc_cpufreq_verify,
0573 .target = pcc_cpufreq_target,
0574 .init = pcc_cpufreq_cpu_init,
0575 .exit = pcc_cpufreq_cpu_exit,
0576 .name = "pcc-cpufreq",
0577 };
0578
0579 static int __init pcc_cpufreq_init(void)
0580 {
0581 int ret;
0582
0583
0584 if (cpufreq_get_current_driver())
0585 return -EEXIST;
0586
0587 if (acpi_disabled)
0588 return -ENODEV;
0589
0590 ret = pcc_cpufreq_probe();
0591 if (ret) {
0592 pr_debug("pcc_cpufreq_init: PCCH evaluation failed\n");
0593 return ret;
0594 }
0595
0596 if (num_present_cpus() > 4) {
0597 pcc_cpufreq_driver.flags |= CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING;
0598 pr_err("%s: Too many CPUs, dynamic performance scaling disabled\n",
0599 __func__);
0600 pr_err("%s: Try to enable another scaling driver through BIOS settings\n",
0601 __func__);
0602 pr_err("%s: and complain to the system vendor\n", __func__);
0603 }
0604
0605 ret = cpufreq_register_driver(&pcc_cpufreq_driver);
0606
0607 return ret;
0608 }
0609
0610 static void __exit pcc_cpufreq_exit(void)
0611 {
0612 cpufreq_unregister_driver(&pcc_cpufreq_driver);
0613
0614 pcc_clear_mapping();
0615
0616 free_percpu(pcc_cpu_info);
0617 }
0618
0619 static const struct acpi_device_id __maybe_unused processor_device_ids[] = {
0620 {ACPI_PROCESSOR_OBJECT_HID, },
0621 {ACPI_PROCESSOR_DEVICE_HID, },
0622 {},
0623 };
0624 MODULE_DEVICE_TABLE(acpi, processor_device_ids);
0625
0626 MODULE_AUTHOR("Matthew Garrett, Naga Chumbalkar");
0627 MODULE_VERSION(PCC_VERSION);
0628 MODULE_DESCRIPTION("Processor Clocking Control interface driver");
0629 MODULE_LICENSE("GPL");
0630
0631 late_initcall(pcc_cpufreq_init);
0632 module_exit(pcc_cpufreq_exit);