Commit c4ba198c authored by heppen's avatar heppen
Browse files

cpufreq: CPPC: 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 and energy perf in the
cppc_cpufreq driver.

Signed-off-by: default avatarPeng He <hepeng68@huawei.com>
parent b718dd52
Loading
Loading
Loading
Loading
+39 −0
Original line number Diff line number Diff line
@@ -268,6 +268,45 @@ Description: Discover CPUs in the same CPU frequency coordination domain
		This file is only present if the acpi-cpufreq or the cppc-cpufreq
		drivers are 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 && ARM64
    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 ACPI_CPPC_CPUFREQ_FIE
	bool "Frequency Invariance support for CPPC cpufreq driver"
	depends on ACPI_CPPC_CPUFREQ && GENERIC_ARCH_TOPOLOGY
+108 −0
Original line number Diff line number Diff line
@@ -832,10 +832,118 @@ static ssize_t show_freqdomain_cpus(struct cpufreq_policy *policy, char *buf)

	return cpufreq_show_cpus(cpu_data->shared_cpu_map, buf);
}

#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);

	/* show "<unsupported>" when this register is not supported by cpc */
	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 val;
	int ret;

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

	/* show "<unsupported>" when this register is not supported by cpc */
	if (ret == -EOPNOTSUPP)
		return sysfs_emit(buf, "%s\n", "<unsupported>");

	if (ret)
		return ret;

	return sysfs_emit(buf, "%lld\n", val);
}

#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);
#endif // CONFIG_CPPC_CPUFREQ_SYSFS_INTERFACE

cpufreq_freq_attr_ro(freqdomain_cpus);

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