Skip to content

Commit

Permalink
Merge branch 'pm-cpufreq'
Browse files Browse the repository at this point in the history
* pm-cpufreq:
  Revert "cpufreq: intel_pstate: Process HWP Guaranteed change notification"
  cpufreq: mediatek-hw: Add support for CPUFREQ HW
  cpufreq: Add of_perf_domain_get_sharing_cpumask
  dt-bindings: cpufreq: add bindings for MediaTek cpufreq HW
  cpufreq: Remove ready() callback
  cpufreq: sh: Remove sh_cpufreq_cpu_ready()
  cpufreq: acpi: Remove acpi_cpufreq_cpu_ready()
  cpufreq: qcom-hw: Set dvfs_possible_from_any_cpu cpufreq driver flag
  cpufreq: blocklist more Qualcomm platforms in cpufreq-dt-platdev
  cpufreq: qcom-cpufreq-hw: Add dcvs interrupt support
  cpufreq: scmi: Use .register_em() to register with energy model
  cpufreq: vexpress: Use .register_em() to register with energy model
  cpufreq: scpi: Use .register_em() to register with energy model
  cpufreq: qcom-cpufreq-hw: Use .register_em() to register with energy model
  cpufreq: omap: Use .register_em() to register with energy model
  cpufreq: mediatek: Use .register_em() to register with energy model
  cpufreq: imx6q: Use .register_em() to register with energy model
  cpufreq: dt: Use .register_em() to register with energy model
  cpufreq: Add callback to register with energy model
  cpufreq: vexpress: Set CPUFREQ_IS_COOLING_DEV flag
  • Loading branch information
Rafael J. Wysocki committed Sep 8, 2021
2 parents 5cbba60 + 27de8d5 commit eabf9e6
Show file tree
Hide file tree
Showing 21 changed files with 684 additions and 128 deletions.
3 changes: 0 additions & 3 deletions Documentation/cpu-freq/cpu-drivers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,6 @@ And optionally
.resume - A pointer to a per-policy resume function which is called
with interrupts disabled and _before_ the governor is started again.

.ready - A pointer to a per-policy ready function which is called after
the policy is fully initialized.

.attr - A pointer to a NULL-terminated list of "struct freq_attr" which
allow to export values to sysfs.

Expand Down
70 changes: 70 additions & 0 deletions Documentation/devicetree/bindings/cpufreq/cpufreq-mediatek-hw.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/cpufreq/cpufreq-mediatek-hw.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#

title: MediaTek's CPUFREQ Bindings

maintainers:
- Hector Yuan <hector.yuan@mediatek.com>

description:
CPUFREQ HW is a hardware engine used by MediaTek SoCs to
manage frequency in hardware. It is capable of controlling
frequency for multiple clusters.

properties:
compatible:
const: mediatek,cpufreq-hw

reg:
minItems: 1
maxItems: 2
description:
Addresses and sizes for the memory of the HW bases in
each frequency domain. Each entry corresponds to
a register bank for each frequency domain present.

"#performance-domain-cells":
description:
Number of cells in a performance domain specifier.
Set const to 1 here for nodes providing multiple
performance domains.
const: 1

required:
- compatible
- reg
- "#performance-domain-cells"

additionalProperties: false

examples:
- |
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a55";
enable-method = "psci";
performance-domains = <&performance 0>;
reg = <0x000>;
};
};
/* ... */
soc {
#address-cells = <2>;
#size-cells = <2>;
performance: performance-controller@11bc00 {
compatible = "mediatek,cpufreq-hw";
reg = <0 0x0011bc10 0 0x120>, <0 0x0011bd30 0 0x120>;
#performance-domain-cells = <1>;
};
};
2 changes: 0 additions & 2 deletions Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,6 @@ CPUfreq核心层注册一个cpufreq_driver结构体。
.resume - 一个指向per-policy恢复函数的指针,该函数在关中断且在调节器再一次开始前被
调用。

.ready - 一个指向per-policy准备函数的指针,该函数在策略完全初始化之后被调用。

.attr - 一个指向NULL结尾的"struct freq_attr"列表的指针,该函数允许导出值到
sysfs。

Expand Down
2 changes: 2 additions & 0 deletions drivers/base/arch_topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ void topology_set_freq_scale(const struct cpumask *cpus, unsigned long cur_freq,
}

DEFINE_PER_CPU(unsigned long, cpu_scale) = SCHED_CAPACITY_SCALE;
EXPORT_PER_CPU_SYMBOL_GPL(cpu_scale);

void topology_set_cpu_scale(unsigned int cpu, unsigned long capacity)
{
Expand All @@ -165,6 +166,7 @@ void topology_set_thermal_pressure(const struct cpumask *cpus,
for_each_cpu(cpu, cpus)
WRITE_ONCE(per_cpu(thermal_pressure, cpu), th_pressure);
}
EXPORT_SYMBOL_GPL(topology_set_thermal_pressure);

static ssize_t cpu_capacity_show(struct device *dev,
struct device_attribute *attr,
Expand Down
12 changes: 12 additions & 0 deletions drivers/cpufreq/Kconfig.arm
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,18 @@ config ARM_MEDIATEK_CPUFREQ
help
This adds the CPUFreq driver support for MediaTek SoCs.

config ARM_MEDIATEK_CPUFREQ_HW
tristate "MediaTek CPUFreq HW driver"
depends on ARCH_MEDIATEK || COMPILE_TEST
default m
help
Support for the CPUFreq HW driver.
Some MediaTek chipsets have a HW engine to offload the steps
necessary for changing the frequency of the CPUs. Firmware loaded
in this engine exposes a programming interface to the OS.
The driver implements the cpufreq interface for this HW engine.
Say Y if you want to support CPUFreq HW.

config ARM_OMAP2PLUS_CPUFREQ
bool "TI OMAP2+"
depends on ARCH_OMAP2PLUS
Expand Down
1 change: 1 addition & 0 deletions drivers/cpufreq/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o
obj-$(CONFIG_ARM_IMX_CPUFREQ_DT) += imx-cpufreq-dt.o
obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o
obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ) += mediatek-cpufreq.o
obj-$(CONFIG_ARM_MEDIATEK_CPUFREQ_HW) += mediatek-cpufreq-hw.o
obj-$(CONFIG_MACH_MVEBU_V7) += mvebu-cpufreq.o
obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o
obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o
Expand Down
14 changes: 3 additions & 11 deletions drivers/cpufreq/acpi-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,9 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
policy->fast_switch_possible = !acpi_pstate_strict &&
!(policy_is_shared(policy) && policy->shared_type != CPUFREQ_SHARED_TYPE_ANY);

if (perf->states[0].core_frequency * 1000 != freq_table[0].frequency)
pr_warn(FW_WARN "P-state 0 is not max freq\n");

return result;

err_unreg:
Expand Down Expand Up @@ -918,16 +921,6 @@ static int acpi_cpufreq_cpu_exit(struct cpufreq_policy *policy)
return 0;
}

static void acpi_cpufreq_cpu_ready(struct cpufreq_policy *policy)
{
struct acpi_processor_performance *perf = per_cpu_ptr(acpi_perf_data,
policy->cpu);
unsigned int freq = policy->freq_table[0].frequency;

if (perf->states[0].core_frequency * 1000 != freq)
pr_warn(FW_WARN "P-state 0 is not max freq\n");
}

static int acpi_cpufreq_resume(struct cpufreq_policy *policy)
{
struct acpi_cpufreq_data *data = policy->driver_data;
Expand Down Expand Up @@ -955,7 +948,6 @@ static struct cpufreq_driver acpi_cpufreq_driver = {
.bios_limit = acpi_processor_get_bios_limit,
.init = acpi_cpufreq_cpu_init,
.exit = acpi_cpufreq_cpu_exit,
.ready = acpi_cpufreq_cpu_ready,
.resume = acpi_cpufreq_resume,
.name = "acpi-cpufreq",
.attr = acpi_cpufreq_attr,
Expand Down
4 changes: 4 additions & 0 deletions drivers/cpufreq/cpufreq-dt-platdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,15 @@ static const struct of_device_id blocklist[] __initconst = {
{ .compatible = "qcom,apq8096", },
{ .compatible = "qcom,msm8996", },
{ .compatible = "qcom,qcs404", },
{ .compatible = "qcom,sa8155p" },
{ .compatible = "qcom,sc7180", },
{ .compatible = "qcom,sc7280", },
{ .compatible = "qcom,sc8180x", },
{ .compatible = "qcom,sdm845", },
{ .compatible = "qcom,sm6350", },
{ .compatible = "qcom,sm8150", },
{ .compatible = "qcom,sm8250", },
{ .compatible = "qcom,sm8350", },

{ .compatible = "st,stih407", },
{ .compatible = "st,stih410", },
Expand Down
3 changes: 1 addition & 2 deletions drivers/cpufreq/cpufreq-dt.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,6 @@ static int cpufreq_init(struct cpufreq_policy *policy)
cpufreq_dt_attr[1] = &cpufreq_freq_attr_scaling_boost_freqs;
}

dev_pm_opp_of_register_em(cpu_dev, policy->cpus);

return 0;

out_clk_put:
Expand Down Expand Up @@ -184,6 +182,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
.exit = cpufreq_exit,
.online = cpufreq_online,
.offline = cpufreq_offline,
.register_em = cpufreq_register_em_with_opp,
.name = "cpufreq-dt",
.attr = cpufreq_dt_attr,
.suspend = cpufreq_generic_suspend,
Expand Down
17 changes: 13 additions & 4 deletions drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1491,6 +1491,19 @@ static int cpufreq_online(unsigned int cpu)
write_lock_irqsave(&cpufreq_driver_lock, flags);
list_add(&policy->policy_list, &cpufreq_policy_list);
write_unlock_irqrestore(&cpufreq_driver_lock, flags);

/*
* Register with the energy model before
* sched_cpufreq_governor_change() is called, which will result
* in rebuilding of the sched domains, which should only be done
* once the energy model is properly initialized for the policy
* first.
*
* Also, this should be called before the policy is registered
* with cooling framework.
*/
if (cpufreq_driver->register_em)
cpufreq_driver->register_em(policy);
}

ret = cpufreq_init_policy(policy);
Expand All @@ -1504,10 +1517,6 @@ static int cpufreq_online(unsigned int cpu)

kobject_uevent(&policy->kobj, KOBJ_ADD);

/* Callback for handling stuff after policy is ready */
if (cpufreq_driver->ready)
cpufreq_driver->ready(policy);

if (cpufreq_thermal_control_enabled(cpufreq_driver))
policy->cdev = of_cpufreq_cooling_register(policy);

Expand Down
2 changes: 1 addition & 1 deletion drivers/cpufreq/imx6q-cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,6 @@ static int imx6q_cpufreq_init(struct cpufreq_policy *policy)
policy->clk = clks[ARM].clk;
cpufreq_generic_init(policy, freq_table, transition_latency);
policy->suspend_freq = max_freq;
dev_pm_opp_of_register_em(cpu_dev, policy->cpus);

return 0;
}
Expand All @@ -204,6 +203,7 @@ static struct cpufreq_driver imx6q_cpufreq_driver = {
.target_index = imx6q_set_target,
.get = cpufreq_generic_get,
.init = imx6q_cpufreq_init,
.register_em = cpufreq_register_em_with_opp,
.name = "imx6q-cpufreq",
.attr = cpufreq_generic_attr,
.suspend = cpufreq_generic_suspend,
Expand Down
39 changes: 0 additions & 39 deletions drivers/cpufreq/intel_pstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@
#include <asm/cpu_device_id.h>
#include <asm/cpufeature.h>
#include <asm/intel-family.h>
#include "../drivers/thermal/intel/thermal_interrupt.h"

#define INTEL_PSTATE_SAMPLING_INTERVAL (10 * NSEC_PER_MSEC)

Expand Down Expand Up @@ -220,7 +219,6 @@ struct global_params {
* @sched_flags: Store scheduler flags for possible cross CPU update
* @hwp_boost_min: Last HWP boosted min performance
* @suspended: Whether or not the driver has been suspended.
* @hwp_notify_work: workqueue for HWP notifications.
*
* This structure stores per CPU instance data for all CPUs.
*/
Expand Down Expand Up @@ -259,7 +257,6 @@ struct cpudata {
unsigned int sched_flags;
u32 hwp_boost_min;
bool suspended;
struct delayed_work hwp_notify_work;
};

static struct cpudata **all_cpu_data;
Expand Down Expand Up @@ -1628,40 +1625,6 @@ static void intel_pstate_sysfs_hide_hwp_dynamic_boost(void)

/************************** sysfs end ************************/

static void intel_pstate_notify_work(struct work_struct *work)
{
mutex_lock(&intel_pstate_driver_lock);
cpufreq_update_policy(smp_processor_id());
wrmsrl(MSR_HWP_STATUS, 0);
mutex_unlock(&intel_pstate_driver_lock);
}

void notify_hwp_interrupt(void)
{
unsigned int this_cpu = smp_processor_id();
struct cpudata *cpudata;
u64 value;

if (!hwp_active || !boot_cpu_has(X86_FEATURE_HWP_NOTIFY))
return;

rdmsrl(MSR_HWP_STATUS, value);
if (!(value & 0x01))
return;

cpudata = all_cpu_data[this_cpu];
schedule_delayed_work_on(this_cpu, &cpudata->hwp_notify_work, msecs_to_jiffies(10));
}

static void intel_pstate_enable_hwp_interrupt(struct cpudata *cpudata)
{
/* Enable HWP notification interrupt for guaranteed performance change */
if (boot_cpu_has(X86_FEATURE_HWP_NOTIFY)) {
INIT_DELAYED_WORK(&cpudata->hwp_notify_work, intel_pstate_notify_work);
wrmsrl_on_cpu(cpudata->cpu, MSR_HWP_INTERRUPT, 0x01);
}
}

static void intel_pstate_hwp_enable(struct cpudata *cpudata)
{
/* First disable HWP notification interrupt as we don't process them */
Expand All @@ -1671,8 +1634,6 @@ static void intel_pstate_hwp_enable(struct cpudata *cpudata)
wrmsrl_on_cpu(cpudata->cpu, MSR_PM_ENABLE, 0x1);
if (cpudata->epp_default == -EINVAL)
cpudata->epp_default = intel_pstate_get_epp(cpudata, 0);

intel_pstate_enable_hwp_interrupt(cpudata);
}

static int atom_get_min_pstate(void)
Expand Down
Loading

0 comments on commit eabf9e6

Please sign in to comment.