Commit c3fe0dc6 authored by heppen's avatar heppen
Browse files

cpufreq: Add SEEP governor for hardware-managed P-states

huawei inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IB5JJG


CVE: NA

--------------------------------------------------

Add a new CPUFreq governor 'seep' designed for platforms with
hardware-managed P-states through CPPC (Collaborative Processor
Performance Control). This governor enables the hardware's autonomous
frequency selection capability, allowing the processor to manage its
own frequency based on workload characteristics.

The SEEP governor requires:
- cppc_cpufreq driver
- Platform support for CPPC features:
  * Autonomous selection (auto_sel)
  * Autonomous activity window (auto_act_window)
  * Energy Performance Preference (epp)

Two per-policy sysfs interfaces are provided:
- auto_act_window: Control the hardware's frequency scaling window
- energy_perf: Bias between performance and energy efficiency

Signed-off-by: default avatarPeng He <hepeng68@huawei.com>
parent 499f163a
Loading
Loading
Loading
Loading
+42 −0
Original line number Diff line number Diff line
@@ -590,6 +590,48 @@ This governor exposes the following tunables:
	It effectively causes the frequency to go down ``sampling_down_factor``
	times slower than it ramps up.

``seep``
------------

This governor is specifically designed for platforms with hardware-managed P-states
through CPPC (Collaborative Processor Performance Control). Unlike other governors
that implement their own frequency scaling algorithms, the ``seep`` governor
delegates the P-state selection to the hardware/firmware by enabling CPPC
autonomous mode.

The governor requires the ``cppc_cpufreq`` driver and the platform must support
three key CPPC capabilities:
 * Autonomous selection (auto_sel)
 * Autonomous activity window (auto_act_window)
 * Energy-Performance Preference (EPP)

When this governor is attached to a policy, it enables the hardware autonomous
mode, allowing the processor's firmware to directly manage frequency scaling based
on workload characteristics. The actual P-state selection algorithms are
implemented in firmware/hardware rather than in the operating system.

This governor exposes the following tunables (per-policy):

``auto_act_window``
	The time window (in microseconds) used by the hardware/firmware to observe
	and evaluate workload characteristics before making P-state decisions.
	A smaller window makes the algorithm more responsive but potentially less
	stable, while a larger window provides more stable but less responsive
	frequency scaling.

``energy_perf``
	A value between 0 and 255 that biases the hardware's frequency scaling
	decisions between performance and energy efficiency. Lower values (closer
	to 0) favor performance at the expense of power consumption, while higher
	values (closer to 255) favor energy efficiency but may impact performance.

The ``seep`` governor is particularly suitable for platforms where the hardware
has more accurate and fine-grained information about the system's power and
thermal constraints than the operating system. It can potentially provide better
energy efficiency than software-based governors while maintaining good
performance, as the hardware can make faster and more informed P-state
decisions.


Frequency Boost Support
=======================
+1 −0
Original line number Diff line number Diff line
@@ -658,6 +658,7 @@ CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
CONFIG_CPU_FREQ_GOV_SCHEDUTIL=y
CONFIG_CPU_FREQ_GOV_SEEP=m

#
# CPU frequency scaling drivers
+20 −0
Original line number Diff line number Diff line
@@ -203,6 +203,26 @@ config CPU_FREQ_GOV_SCHEDUTIL

	  If in doubt, say N.

config CPU_FREQ_GOV_SEEP
	tristate "'seep' cpufreq policy governor"
	depends on ACPI_CPPC_CPUFREQ || ARM64
	select CPPC_CPUFREQ_SYSFS_INTERFACE
	select CPU_FREQ_GOV_COMMON
	help
	  'seep' - This governor is designed for platforms with hardware-managed
	  P-states through CPPC (Collaborative Processor Performance Control).
	  It enables the hardware's autonomous frequency selection capability,
	  allowing the processor to manage its own frequency based on workload.

	  This governor requires the cppc_cpufreq driver and platform support
	  for CPPC features including auto-selection, autonomous activity window,
	  and energy-performance preference.

	  To compile this driver as a module, choose M here: the
	  module will be called cpufreq_seep.

	  If in doubt, say N.

comment "CPU frequency scaling drivers"

config CPUFREQ_DT
+1 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_POWERSAVE) += cpufreq_powersave.o
obj-$(CONFIG_CPU_FREQ_GOV_USERSPACE)	+= cpufreq_userspace.o
obj-$(CONFIG_CPU_FREQ_GOV_ONDEMAND)	+= cpufreq_ondemand.o
obj-$(CONFIG_CPU_FREQ_GOV_CONSERVATIVE)	+= cpufreq_conservative.o
obj-$(CONFIG_CPU_FREQ_GOV_SEEP)		+= cpufreq_seep.o
obj-$(CONFIG_CPU_FREQ_GOV_COMMON)		+= cpufreq_governor.o
obj-$(CONFIG_CPU_FREQ_GOV_ATTR_SET)	+= cpufreq_governor_attr_set.o

+109 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 *  drivers/cpufreq/cpufreq_seep.c
 *
 *  Copyright (C) 2024 heppen <hepeng68@huawei.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/cpufreq.h>
#include <linux/init.h>
#include <linux/module.h>
#include <acpi/cppc_acpi.h>

/*
 * Check if the platform supports required CPPC features for SEEP governor:
 * - auto_sel: Hardware-managed P-state selection
 * - auto_act_window: Autonomous activity window
 * - epp: Energy Performance Preference
 */
static bool seep_supported(void)
{
	const char *driver;
	u64 val;
	int ret;

	driver = cpufreq_get_current_driver();
	if (!driver || strcmp(driver, "cppc_cpufreq"))
		return false;

	ret = cppc_get_auto_sel(0, &val);
	if (ret)
		return false;

	ret = cppc_get_auto_act_window(0, &val);
	if (ret)
		return false;

	ret = cppc_get_epp_perf(0, &val);
	if (ret)
		return false;

	return true;
}

/*
 * Start the SEEP governor for the given policy.
 * Enable hardware-managed P-state selection.
 */
static int cpufreq_gov_seep_start(struct cpufreq_policy *policy)
{
	int ret;

	/* Enable BIOS frequency Scaling */
	ret = cppc_set_auto_sel(policy->cpu, 1);
	if (ret)
		pr_err("Failed to enable auto_sel: %d\n", ret);
	return ret;
}

/*
 * Stop the SEEP governor for the given policy.
 * Disable hardware-managed P-state selection.
 */
static void cpufreq_gov_seep_stop(struct cpufreq_policy *policy)
{
	int ret;

	/* Disable BIOS frequency Scaling */
	ret = cppc_set_auto_sel(policy->cpu, 0);
	if (ret)
		pr_err("Failed to disable auto_sel: %d\n", ret);
}

static struct cpufreq_governor cpufreq_gov_seep = {
	.name = "seep",
	.start = cpufreq_gov_seep_start,
	.stop = cpufreq_gov_seep_stop,
	.owner = THIS_MODULE,
};

static int __init cpufreq_gov_seep_init(void)
{
	if (!seep_supported()) {
		pr_err("SEEP governor requires cppc_cpufreq driver and CPPC feature support\n");
		return -ENODEV;
	}

	return cpufreq_register_governor(&cpufreq_gov_seep);
}

static void __exit cpufreq_gov_seep_exit(void)
{
	cpufreq_unregister_governor(&cpufreq_gov_seep);
}

#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_SEEP
struct cpufreq_governor *cpufreq_default_governor(void)
{
	return &cpufreq_gov_seep;
}
#endif

module_init(cpufreq_gov_seep_init);
module_exit(cpufreq_gov_seep_exit);

MODULE_AUTHOR("heppen <hepeng68@huawei.com>");
MODULE_DESCRIPTION("CPUfreq policy governor 'seep'");
MODULE_LICENSE("GPL");