Commit 499f163a authored by heppen's avatar heppen
Browse files

Support for auto_act_window and energy_perf in cppc_cpufreq

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


CVE: NA

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

Add sysfs interfaces for CPPC auto_act_window andenergy_perf
energy_perf in the cppc_cpufreq driver

Signed-off-by: default avatarPeng He <hepeng68@huawei.com>
parent 6d474065
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -266,6 +266,44 @@ Description: Discover CPUs in the same CPU frequency coordination domain

		This file is only present if the acpi-cpufreq driver is in use.

What:		/sys/devices/system/cpu/cpuX/cpufreq/auto_act_window
Date:		October 2024
Contact:	linux-pm@vger.kernel.org
Description:	Autonomous activity window

		This file indicates a moving utilization sensitivity window to
		the platform's autonomous selection policy.

		Read/write an integer represents autonomous activity window (in
		microseconds) from/to this file. The max value to write is
		1270000000 but the max significand is 127. This means that if 128
		is written to this file, 127 will be stored. If the value is
		greater than 130, only the first two digits will be saved as
		significand.

		Writing a zero value to this file enable the platform to
		determine an appropriate Activity Window depending on the workload.

		Writing to this file only has meaning when Autonomous Selection is
		enabled.

		This file only presents if the cppc-cpufreq driver is in use.

What:		/sys/devices/system/cpu/cpuX/cpufreq/energy_perf
Date:		October 2024
Contact:	linux-pm@vger.kernel.org
Description:	Energy performance preference

		Read/write an 8-bit integer from/to this file. This file
		represents a range of values from 0 (performance preference) to
		0xFF (energy efficiency preference) that influences the rate of
		performance increase/decrease and the result of the hardware's
		energy efficiency and performance optimization policies.

		Writing to this file only has meaning when Autonomous Selection is
		enabled.

		This file only presents if the cppc-cpufreq driver is in use.

What:		/sys/devices/system/cpu/cpu*/cache/index3/cache_disable_{0,1}
Date:		August 2008
+11 −0
Original line number Diff line number Diff line
@@ -19,6 +19,17 @@ config ACPI_CPPC_CPUFREQ

	  If in doubt, say N.

config CPPC_CPUFREQ_SYSFS_INTERFACE
    bool "Enable CPPC CPUFreq sysfs tuning interfaces"
    depends on ACPI_CPPC_CPUFREQ
    default n
    help
      This enables sysfs interfaces for CPPC CPUFreq driver including
      auto_act_window and energy_perf. These interfaces allow users
      to tune CPPC parameters at runtime.

      If unsure, say N.

config ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM
	tristate "Allwinner nvmem based SUN50I CPUFreq driver"
	depends on ARCH_SUNXI
+111 −0
Original line number Diff line number Diff line
@@ -438,6 +438,114 @@ static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state)
	return 0;
}

#ifdef CONFIG_CPPC_CPUFREQ_SYSFS_INTERFACE

#define AUTO_ACT_WINDOW_SIG_BIT_SIZE (7)
#define AUTO_ACT_WINDOW_EXP_BIT_SIZE (3)
#define AUTO_ACT_WINDOW_MAX_SIG ((1 << AUTO_ACT_WINDOW_SIG_BIT_SIZE) - 1)
#define AUTO_ACT_WINDOW_MAX_EXP ((1 << AUTO_ACT_WINDOW_EXP_BIT_SIZE) - 1)
/* AUTO_ACT_WINDOW_MAX_SIG is 127, so 128 and 129 will decay to 127 when writing */
#define AUTO_ACT_WINDOW_SIG_CARRY_THRESH 129

static ssize_t show_auto_act_window(struct cpufreq_policy *policy, char *buf)
{
	unsigned int exp;
	u64 val, sig;
	int ret;

	ret = cppc_get_auto_act_window(policy->cpu, &val);

	if (ret == -EOPNOTSUPP)
		return sysfs_emit(buf, "%s\n", "<unsupported>");

	if (ret)
		return ret;

	sig = val & AUTO_ACT_WINDOW_MAX_SIG;
	exp = (val >> AUTO_ACT_WINDOW_SIG_BIT_SIZE) & AUTO_ACT_WINDOW_MAX_EXP;

	return sysfs_emit(buf, "%llu\n", sig * int_pow(10, exp));
}

static ssize_t store_auto_act_window(struct cpufreq_policy *policy,
				     const char *buf, size_t count)
{
	unsigned long usec;
	int digits = 0;
	int ret;

	ret = kstrtoul(buf, 0, &usec);
	if (ret)
		return ret;

	if (usec > (AUTO_ACT_WINDOW_MAX_SIG * int_pow(10, AUTO_ACT_WINDOW_MAX_EXP)))
		return -EINVAL;

	while (usec > AUTO_ACT_WINDOW_SIG_CARRY_THRESH) {
		usec /= 10;
		digits += 1;
	}

	if (usec > AUTO_ACT_WINDOW_MAX_SIG)
		usec = AUTO_ACT_WINDOW_MAX_SIG;

	ret = cppc_set_auto_act_window(
		policy->cpu, (digits << AUTO_ACT_WINDOW_SIG_BIT_SIZE) + usec);

	if (ret)
		return ret;

	return count;
}

static ssize_t show_energy_perf(struct cpufreq_policy *policy, char *buf)
{
	u64 perf_value;
	int ret;

	ret = cppc_get_epp_perf(policy->cpu, &perf_value);
	if (ret == -EOPNOTSUPP)
		return sysfs_emit(buf, "%s\n", "<unsupported>");

	if (ret)
		return ret;

	return sysfs_emit(buf, "%llu\n", perf_value);
}

#define ENERGY_PERF_MAX (0xFF)

static ssize_t store_energy_perf(struct cpufreq_policy *policy,
				 const char *buf, size_t count)
{
	unsigned long val;
	int ret;

	ret = kstrtoul(buf, 0, &val);
	if (ret)
		return ret;

	if (val > ENERGY_PERF_MAX)
		return -EINVAL;

	ret = cppc_set_epp(policy->cpu, val);
	if (ret)
		return ret;

	return count;
}

cpufreq_freq_attr_rw(auto_act_window);
cpufreq_freq_attr_rw(energy_perf);

static struct freq_attr *cppc_cpufreq_attr[] = {
	&auto_act_window,
	&energy_perf,
	NULL,
};
#endif // CONFIG_CPPC_CPUFREQ_SYSFS_INTERFACE


static struct cpufreq_driver cppc_cpufreq_driver = {
	.flags = CPUFREQ_CONST_LOOPS,
	.verify = cppc_verify_policy,
@@ -446,6 +554,9 @@ static struct cpufreq_driver cppc_cpufreq_driver = {
	.init = cppc_cpufreq_cpu_init,
	.stop_cpu = cppc_cpufreq_stop_cpu,
	.set_boost = cppc_cpufreq_set_boost,
#ifdef CONFIG_CPPC_CPUFREQ_SYSFS_INTERFACE
	.attr = cppc_cpufreq_attr,
#endif
	.name = "cppc_cpufreq",
};