Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f1c7842e authored by Rafael J. Wysocki's avatar Rafael J. Wysocki
Browse files

Merge branches 'pm-cpufreq', 'intel_pstate' and 'pm-cpuidle'

* pm-cpufreq:
  cpufreq / CPPC: Initialize policy->min to lowest nonlinear performance
  cpufreq: sfi: make freq_table static
  cpufreq: exynos5440: Fix inconsistent indenting
  cpufreq: imx6q: imx6ull should use the same flow as imx6ul
  cpufreq: dt: Add support for hi3660

* intel_pstate:
  cpufreq: Update scaling_cur_freq documentation
  cpufreq: intel_pstate: Clean up after performance governor changes
  intel_pstate: skip scheduler hook when in "performance" mode
  intel_pstate: delete scheduler hook in HWP mode
  x86: use common aperfmperf_khz_on_cpu() to calculate KHz using APERF/MPERF
  cpufreq: intel_pstate: Remove max/min fractions to limit performance
  x86: do not use cpufreq_quick_get() for /proc/cpuinfo "cpu MHz"

* pm-cpuidle:
  cpuidle: menu: allow state 0 to be disabled
  intel_idle: Use more common logging style
  x86/ACPI/cstate: Allow ACPI C1 FFH MWAIT use on AMD systems
  ARM: cpuidle: Support asymmetric idle definition
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -269,16 +269,16 @@ are the following:
``scaling_cur_freq``
	Current frequency of all of the CPUs belonging to this policy (in kHz).

	For the majority of scaling drivers, this is the frequency of the last
	P-state requested by the driver from the hardware using the scaling
	In the majority of cases, this is the frequency of the last P-state
	requested by the scaling driver from the hardware using the scaling
	interface provided by it, which may or may not reflect the frequency
	the CPU is actually running at (due to hardware design and other
	limitations).

	Some scaling drivers (e.g. |intel_pstate|) attempt to provide
	information more precisely reflecting the current CPU frequency through
	this attribute, but that still may not be the exact current CPU
	frequency as seen by the hardware at the moment.
	Some architectures (e.g. ``x86``) may attempt to provide information
	more precisely reflecting the current CPU frequency through this
	attribute, but that still may not be the exact current CPU frequency as
	seen by the hardware at the moment.

``scaling_driver``
	The scaling driver currently in use.
+2 −4
Original line number Diff line number Diff line
@@ -157,10 +157,8 @@ Without HWP, this P-state selection algorithm is always the same regardless of
the processor model and platform configuration.

It selects the maximum P-state it is allowed to use, subject to limits set via
``sysfs``, every time the P-state selection computations are carried out by the
driver's utilization update callback for the given CPU (that does not happen
more often than every 10 ms), but the hardware configuration will not be changed
if the new P-state is the same as the current one.
``sysfs``, every time the driver configuration for the given CPU is updated
(e.g. via ``sysfs``).

This is the default P-state selection algorithm if the
:c:macro:`CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE` kernel configuration option
+2 −1
Original line number Diff line number Diff line
@@ -167,7 +167,8 @@ static int __init ffh_cstate_init(void)
{
	struct cpuinfo_x86 *c = &boot_cpu_data;

	if (c->x86_vendor != X86_VENDOR_INTEL)
	if (c->x86_vendor != X86_VENDOR_INTEL &&
	    c->x86_vendor != X86_VENDOR_AMD)
		return -1;

	cpu_cstate_entry = alloc_percpu(struct cstate_entry);
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ obj-y += common.o
obj-y			+= rdrand.o
obj-y			+= match.o
obj-y			+= bugs.o
obj-$(CONFIG_CPU_FREQ)	+= aperfmperf.o

obj-$(CONFIG_PROC_FS)	+= proc.o
obj-$(CONFIG_X86_FEATURE_NAMES) += capflags.o powerflags.o
+79 −0
Original line number Diff line number Diff line
/*
 * x86 APERF/MPERF KHz calculation for
 * /sys/.../cpufreq/scaling_cur_freq
 *
 * Copyright (C) 2017 Intel Corp.
 * Author: Len Brown <len.brown@intel.com>
 *
 * This file is licensed under GPLv2.
 */

#include <linux/jiffies.h>
#include <linux/math64.h>
#include <linux/percpu.h>
#include <linux/smp.h>

struct aperfmperf_sample {
	unsigned int	khz;
	unsigned long	jiffies;
	u64	aperf;
	u64	mperf;
};

static DEFINE_PER_CPU(struct aperfmperf_sample, samples);

/*
 * aperfmperf_snapshot_khz()
 * On the current CPU, snapshot APERF, MPERF, and jiffies
 * unless we already did it within 10ms
 * calculate kHz, save snapshot
 */
static void aperfmperf_snapshot_khz(void *dummy)
{
	u64 aperf, aperf_delta;
	u64 mperf, mperf_delta;
	struct aperfmperf_sample *s = this_cpu_ptr(&samples);

	/* Don't bother re-computing within 10 ms */
	if (time_before(jiffies, s->jiffies + HZ/100))
		return;

	rdmsrl(MSR_IA32_APERF, aperf);
	rdmsrl(MSR_IA32_MPERF, mperf);

	aperf_delta = aperf - s->aperf;
	mperf_delta = mperf - s->mperf;

	/*
	 * There is no architectural guarantee that MPERF
	 * increments faster than we can read it.
	 */
	if (mperf_delta == 0)
		return;

	/*
	 * if (cpu_khz * aperf_delta) fits into ULLONG_MAX, then
	 *	khz = (cpu_khz * aperf_delta) / mperf_delta
	 */
	if (div64_u64(ULLONG_MAX, cpu_khz) > aperf_delta)
		s->khz = div64_u64((cpu_khz * aperf_delta), mperf_delta);
	else	/* khz = aperf_delta / (mperf_delta / cpu_khz) */
		s->khz = div64_u64(aperf_delta,
			div64_u64(mperf_delta, cpu_khz));
	s->jiffies = jiffies;
	s->aperf = aperf;
	s->mperf = mperf;
}

unsigned int arch_freq_get_on_cpu(int cpu)
{
	if (!cpu_khz)
		return 0;

	if (!static_cpu_has(X86_FEATURE_APERFMPERF))
		return 0;

	smp_call_function_single(cpu, aperfmperf_snapshot_khz, NULL, 1);

	return per_cpu(samples.khz, cpu);
}
Loading