Lines Matching +full:p +full:- +full:states

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * acpi-cpufreq.c - ACPI Processor P-States Driver
7 * Copyright (C) 2002 - 2004 Dominik Brodowski <linux@brodo.de>
39 MODULE_DESCRIPTION("ACPI Processor P-States Driver");
67 return per_cpu_ptr(acpi_perf_data, data->acpi_perf_cpu); in to_perf_data()
110 return -EINVAL; in boost_set_msr()
133 on_each_cpu_mask(policy->cpus, boost_set_msr_each, in set_boost()
136 cpumask_pr_args(policy->cpus), str_enabled_disabled(val)); in set_boost()
143 struct acpi_cpufreq_data *data = policy->driver_data; in show_freqdomain_cpus()
146 return -ENODEV; in show_freqdomain_cpus()
148 return cpufreq_show_cpus(data->freqdomain_cpus, buf); in show_freqdomain_cpus()
161 return -EINVAL; in store_cpb()
165 return -EINVAL; in store_cpb()
198 struct acpi_cpufreq_data *data = policy->driver_data; in extract_io()
204 for (i = 0; i < perf->state_count; i++) { in extract_io()
205 if (value == perf->states[i].status) in extract_io()
206 return policy->freq_table[i].frequency; in extract_io()
213 struct acpi_cpufreq_data *data = policy->driver_data; in extract_msr()
226 cpufreq_for_each_entry(pos, policy->freq_table) in extract_msr()
227 if (msr == perf->states[pos->driver_data].status) in extract_msr()
228 return pos->frequency; in extract_msr()
229 return policy->freq_table[0].frequency; in extract_msr()
234 struct acpi_cpufreq_data *data = policy->driver_data; in extract_freq()
236 switch (data->cpu_feature) { in extract_freq()
281 acpi_os_read_port(reg->address, &val, reg->bit_width); in cpu_freq_read_io()
287 acpi_os_write_port(reg->address, val, reg->bit_width); in cpu_freq_write_io()
304 cmd->val = cmd->func.read(cmd->reg); in do_drv_read()
311 .reg = &perf->control_register, in drv_read()
312 .func.read = data->cpu_freq_read, in drv_read()
326 cmd->func.write(cmd->reg, cmd->val); in do_drv_write()
334 .reg = &perf->control_register, in drv_write()
336 .func.write = data->cpu_freq_write, in drv_write()
375 data = policy->driver_data; in get_cur_freq_on_cpu()
376 if (unlikely(!data || !policy->freq_table)) in get_cur_freq_on_cpu()
379 cached_freq = policy->freq_table[to_perf_data(data)->state].frequency; in get_cur_freq_on_cpu()
386 data->resume = 1; in get_cur_freq_on_cpu()
397 struct acpi_cpufreq_data *data = policy->driver_data; in check_freqs()
413 struct acpi_cpufreq_data *data = policy->driver_data; in acpi_cpufreq_target()
420 return -ENODEV; in acpi_cpufreq_target()
424 next_perf_state = policy->freq_table[index].driver_data; in acpi_cpufreq_target()
425 if (perf->state == next_perf_state) { in acpi_cpufreq_target()
426 if (unlikely(data->resume)) { in acpi_cpufreq_target()
427 pr_debug("Called after resume, resetting to P%d\n", in acpi_cpufreq_target()
429 data->resume = 0; in acpi_cpufreq_target()
431 pr_debug("Already at target state (P%d)\n", in acpi_cpufreq_target()
439 * stopped, so we can rely on the stability of policy->cpus. in acpi_cpufreq_target()
441 mask = policy->shared_type == CPUFREQ_SHARED_TYPE_ANY ? in acpi_cpufreq_target()
442 cpumask_of(policy->cpu) : policy->cpus; in acpi_cpufreq_target()
444 drv_write(data, mask, perf->states[next_perf_state].control); in acpi_cpufreq_target()
448 policy->freq_table[index].frequency)) { in acpi_cpufreq_target()
449 pr_debug("%s (%d)\n", __func__, policy->cpu); in acpi_cpufreq_target()
450 result = -EAGAIN; in acpi_cpufreq_target()
455 perf->state = next_perf_state; in acpi_cpufreq_target()
463 struct acpi_cpufreq_data *data = policy->driver_data; in acpi_cpufreq_fast_switch()
471 if (policy->cached_target_freq == target_freq) in acpi_cpufreq_fast_switch()
472 index = policy->cached_resolved_idx; in acpi_cpufreq_fast_switch()
477 entry = &policy->freq_table[index]; in acpi_cpufreq_fast_switch()
478 next_freq = entry->frequency; in acpi_cpufreq_fast_switch()
479 next_perf_state = entry->driver_data; in acpi_cpufreq_fast_switch()
482 if (perf->state == next_perf_state) { in acpi_cpufreq_fast_switch()
483 if (unlikely(data->resume)) in acpi_cpufreq_fast_switch()
484 data->resume = 0; in acpi_cpufreq_fast_switch()
489 data->cpu_freq_write(&perf->control_register, in acpi_cpufreq_fast_switch()
490 perf->states[next_perf_state].control); in acpi_cpufreq_fast_switch()
491 perf->state = next_perf_state; in acpi_cpufreq_fast_switch()
505 unsigned long freqn = perf->states[0].core_frequency * 1000; in acpi_cpufreq_guess_freq()
507 for (i = 0; i < (perf->state_count-1); i++) { in acpi_cpufreq_guess_freq()
509 freqn = perf->states[i+1].core_frequency * 1000; in acpi_cpufreq_guess_freq()
511 perf->state = i; in acpi_cpufreq_guess_freq()
515 perf->state = perf->state_count-1; in acpi_cpufreq_guess_freq()
519 perf->state = 0; in acpi_cpufreq_guess_freq()
520 return perf->states[0].core_frequency * 1000; in acpi_cpufreq_guess_freq()
531 ->shared_cpu_map); in free_acpi_perf_data()
538 * Clear the boost-disable bit on the CPU_DOWN path so that in cpufreq_boost_down_prep()
545 * acpi_cpufreq_early_init - initialize ACPI P-States library
547 * Initialize the ACPI P-States library (drivers/acpi/processor_perflib.c)
560 return -ENOMEM; in acpi_cpufreq_early_init()
564 &per_cpu_ptr(acpi_perf_data, i)->shared_cpu_map, in acpi_cpufreq_early_init()
569 return -ENOMEM; in acpi_cpufreq_early_init()
613 if (c->x86_vendor == X86_VENDOR_INTEL) { in acpi_cpufreq_blacklist()
614 if ((c->x86 == 15) && in acpi_cpufreq_blacklist()
615 (c->x86_model == 6) && in acpi_cpufreq_blacklist()
616 (c->x86_stepping == 8)) { in acpi_cpufreq_blacklist()
617 … Xeon(R) 7100 Errata AL30, processors may lock up on frequency changes: disabling acpi-cpufreq\n"); in acpi_cpufreq_blacklist()
618 return -ENODEV; in acpi_cpufreq_blacklist()
676 unsigned int cpu = policy->cpu; in acpi_cpufreq_cpu_init()
698 return -ENOMEM; in acpi_cpufreq_cpu_init()
700 if (!zalloc_cpumask_var(&data->freqdomain_cpus, GFP_KERNEL)) { in acpi_cpufreq_cpu_init()
701 result = -ENOMEM; in acpi_cpufreq_cpu_init()
706 data->acpi_perf_cpu = cpu; in acpi_cpufreq_cpu_init()
707 policy->driver_data = data; in acpi_cpufreq_cpu_init()
716 policy->shared_type = perf->shared_type; in acpi_cpufreq_cpu_init()
719 * Will let policy->cpus know about dependency only when software in acpi_cpufreq_cpu_init()
722 if (policy->shared_type == CPUFREQ_SHARED_TYPE_ALL || in acpi_cpufreq_cpu_init()
723 policy->shared_type == CPUFREQ_SHARED_TYPE_ANY) { in acpi_cpufreq_cpu_init()
724 cpumask_copy(policy->cpus, perf->shared_cpu_map); in acpi_cpufreq_cpu_init()
726 cpumask_copy(data->freqdomain_cpus, perf->shared_cpu_map); in acpi_cpufreq_cpu_init()
731 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; in acpi_cpufreq_cpu_init()
732 cpumask_copy(policy->cpus, topology_core_cpumask(cpu)); in acpi_cpufreq_cpu_init()
737 cpumask_clear(policy->cpus); in acpi_cpufreq_cpu_init()
738 cpumask_set_cpu(cpu, policy->cpus); in acpi_cpufreq_cpu_init()
739 cpumask_copy(data->freqdomain_cpus, in acpi_cpufreq_cpu_init()
741 policy->shared_type = CPUFREQ_SHARED_TYPE_HW; in acpi_cpufreq_cpu_init()
747 if (perf->state_count <= 1) { in acpi_cpufreq_cpu_init()
748 pr_debug("No P-States\n"); in acpi_cpufreq_cpu_init()
749 result = -ENODEV; in acpi_cpufreq_cpu_init()
753 if (perf->control_register.space_id != perf->status_register.space_id) { in acpi_cpufreq_cpu_init()
754 result = -ENODEV; in acpi_cpufreq_cpu_init()
758 switch (perf->control_register.space_id) { in acpi_cpufreq_cpu_init()
763 result = -ENODEV; in acpi_cpufreq_cpu_init()
767 data->cpu_feature = SYSTEM_IO_CAPABLE; in acpi_cpufreq_cpu_init()
768 data->cpu_freq_read = cpu_freq_read_io; in acpi_cpufreq_cpu_init()
769 data->cpu_freq_write = cpu_freq_write_io; in acpi_cpufreq_cpu_init()
774 data->cpu_feature = SYSTEM_INTEL_MSR_CAPABLE; in acpi_cpufreq_cpu_init()
775 data->cpu_freq_read = cpu_freq_read_intel; in acpi_cpufreq_cpu_init()
776 data->cpu_freq_write = cpu_freq_write_intel; in acpi_cpufreq_cpu_init()
780 data->cpu_feature = SYSTEM_AMD_MSR_CAPABLE; in acpi_cpufreq_cpu_init()
781 data->cpu_freq_read = cpu_freq_read_amd; in acpi_cpufreq_cpu_init()
782 data->cpu_freq_write = cpu_freq_write_amd; in acpi_cpufreq_cpu_init()
785 result = -ENODEV; in acpi_cpufreq_cpu_init()
789 (u32) (perf->control_register.space_id)); in acpi_cpufreq_cpu_init()
790 result = -ENODEV; in acpi_cpufreq_cpu_init()
794 freq_table = kcalloc(perf->state_count + 1, sizeof(*freq_table), in acpi_cpufreq_cpu_init()
797 result = -ENOMEM; in acpi_cpufreq_cpu_init()
802 policy->cpuinfo.transition_latency = 0; in acpi_cpufreq_cpu_init()
803 for (i = 0; i < perf->state_count; i++) { in acpi_cpufreq_cpu_init()
804 if ((perf->states[i].transition_latency * 1000) > in acpi_cpufreq_cpu_init()
805 policy->cpuinfo.transition_latency) in acpi_cpufreq_cpu_init()
806 policy->cpuinfo.transition_latency = in acpi_cpufreq_cpu_init()
807 perf->states[i].transition_latency * 1000; in acpi_cpufreq_cpu_init()
811 if (perf->control_register.space_id == ACPI_ADR_SPACE_FIXED_HARDWARE && in acpi_cpufreq_cpu_init()
812 policy->cpuinfo.transition_latency > 20 * 1000) { in acpi_cpufreq_cpu_init()
813 policy->cpuinfo.transition_latency = 20 * 1000; in acpi_cpufreq_cpu_init()
814 pr_info_once("P-state transition latency capped at 20 uS\n"); in acpi_cpufreq_cpu_init()
818 for (i = 0; i < perf->state_count; i++) { in acpi_cpufreq_cpu_init()
819 if (i > 0 && perf->states[i].core_frequency >= in acpi_cpufreq_cpu_init()
820 freq_table[valid_states-1].frequency / 1000) in acpi_cpufreq_cpu_init()
825 perf->states[i].core_frequency * 1000; in acpi_cpufreq_cpu_init()
840 policy->cpuinfo.max_freq = freq * max_boost_ratio >> SCHED_CAPACITY_SHIFT; in acpi_cpufreq_cpu_init()
844 * scale-invariance code to use the "nominal" performance for in acpi_cpufreq_cpu_init()
851 policy->freq_table = freq_table; in acpi_cpufreq_cpu_init()
852 perf->state = 0; in acpi_cpufreq_cpu_init()
854 switch (perf->control_register.space_id) { in acpi_cpufreq_cpu_init()
857 * The core will not set policy->cur, because in acpi_cpufreq_cpu_init()
858 * cpufreq_driver->get is NULL, so we need to set it here. in acpi_cpufreq_cpu_init()
862 policy->cur = acpi_cpufreq_guess_freq(data, policy->cpu); in acpi_cpufreq_cpu_init()
874 pr_debug("CPU%u - ACPI performance management activated.\n", cpu); in acpi_cpufreq_cpu_init()
875 for (i = 0; i < perf->state_count; i++) in acpi_cpufreq_cpu_init()
877 (i == perf->state ? '*' : ' '), i, in acpi_cpufreq_cpu_init()
878 (u32) perf->states[i].core_frequency, in acpi_cpufreq_cpu_init()
879 (u32) perf->states[i].power, in acpi_cpufreq_cpu_init()
880 (u32) perf->states[i].transition_latency); in acpi_cpufreq_cpu_init()
883 * the first call to ->target() should result in us actually in acpi_cpufreq_cpu_init()
886 data->resume = 1; in acpi_cpufreq_cpu_init()
888 policy->fast_switch_possible = !acpi_pstate_strict && in acpi_cpufreq_cpu_init()
889 !(policy_is_shared(policy) && policy->shared_type != CPUFREQ_SHARED_TYPE_ANY); in acpi_cpufreq_cpu_init()
891 if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency) in acpi_cpufreq_cpu_init()
892 pr_warn(FW_WARN "P-state 0 is not max freq\n"); in acpi_cpufreq_cpu_init()
896 policy->boost_enabled = acpi_cpufreq_driver.boost_enabled; in acpi_cpufreq_cpu_init()
904 free_cpumask_var(data->freqdomain_cpus); in acpi_cpufreq_cpu_init()
907 policy->driver_data = NULL; in acpi_cpufreq_cpu_init()
914 struct acpi_cpufreq_data *data = policy->driver_data; in acpi_cpufreq_cpu_exit()
918 cpufreq_boost_down_prep(policy->cpu); in acpi_cpufreq_cpu_exit()
919 policy->fast_switch_possible = false; in acpi_cpufreq_cpu_exit()
920 policy->driver_data = NULL; in acpi_cpufreq_cpu_exit()
921 acpi_processor_unregister_performance(data->acpi_perf_cpu); in acpi_cpufreq_cpu_exit()
922 free_cpumask_var(data->freqdomain_cpus); in acpi_cpufreq_cpu_exit()
923 kfree(policy->freq_table); in acpi_cpufreq_cpu_exit()
929 struct acpi_cpufreq_data *data = policy->driver_data; in acpi_cpufreq_resume()
933 data->resume = 1; in acpi_cpufreq_resume()
955 .name = "acpi-cpufreq",
975 return -ENODEV; in acpi_cpufreq_probe()
979 return -ENODEV; in acpi_cpufreq_probe()
989 * semantic - per CPU instantiation, but system global effect. in acpi_cpufreq_probe()
1026 .name = "acpi-cpufreq",
1043 "value 0 or non-zero. non-zero -> strict ACPI checks are "
1049 MODULE_ALIAS("platform:acpi-cpufreq");