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

Merge branches 'pm-cpuidle' and 'pm-powercap'

Merge cpuidle updates and power capping updates for 6.12-rc1:

 - Add Granite Rapids Xeon support to intel_idle (Artem Bityutskiy).

 - Disable promotion to C1E on Jasper Lake and Elkhart Lake in
   intel_idle (Kai-Heng Feng).

 - Use scoped device node handling to fix missing of_node_put() and
   simplify walking OF children in the riscv-sbi cpuidle driver (Krzysztof
   Kozlowski).

 - Remove dead code from cpuidle_enter_state() (Dhruva Gole).

 - Change an error pointer to NULL to fix error handling in the
   intel_rapl power capping driver (Dan Carpenter).

 - Fix off by one in get_rpi() in the intel_rapl power capping
   driver (Dan Carpenter).

 - Add support for ArrowLake-U to the intel_rapl power capping
   driver (Sumeet Pawnikar).

 - Fix the energy-pkg event for AMD CPUs in the intel_rapl power capping
   driver (Dhananjay Ugwekar).

 - Add support for AMD family 1Ah processors to the intel_rapl power
   capping driver (Dhananjay Ugwekar).

* pm-cpuidle:
  cpuidle: remove dead code from cpuidle_enter_state()
  cpuidle: riscv-sbi: Simplify with scoped for each OF child loop
  cpuidle: riscv-sbi: Use scoped device node handling to fix missing of_node_put
  intel_idle: Disable promotion to C1E on Jasper Lake and Elkhart Lake
  intel_idle: add Granite Rapids Xeon support

* pm-powercap:
  powercap: intel_rapl: Change an error pointer to NULL
  powercap: intel_rapl: Fix off by one in get_rpi()
  powercap: intel_rapl: Add support for ArrowLake-U platform
  powercap/intel_rapl: Fix the energy-pkg event for AMD CPUs
  powercap/intel_rapl: Add support for AMD family 1Ah
Loading
Loading
Loading
Loading
+9 −19
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@

#define pr_fmt(fmt) "cpuidle-riscv-sbi: " fmt

#include <linux/cleanup.h>
#include <linux/cpuhotplug.h>
#include <linux/cpuidle.h>
#include <linux/cpumask.h>
@@ -236,19 +237,16 @@ static int sbi_cpuidle_dt_init_states(struct device *dev,
{
	struct sbi_cpuidle_data *data = per_cpu_ptr(&sbi_cpuidle_data, cpu);
	struct device_node *state_node;
	struct device_node *cpu_node;
	u32 *states;
	int i, ret;

	cpu_node = of_cpu_device_node_get(cpu);
	struct device_node *cpu_node __free(device_node) = of_cpu_device_node_get(cpu);
	if (!cpu_node)
		return -ENODEV;

	states = devm_kcalloc(dev, state_count, sizeof(*states), GFP_KERNEL);
	if (!states) {
		ret = -ENOMEM;
		goto fail;
	}
	if (!states)
		return -ENOMEM;

	/* Parse SBI specific details from state DT nodes */
	for (i = 1; i < state_count; i++) {
@@ -264,10 +262,8 @@ static int sbi_cpuidle_dt_init_states(struct device *dev,

		pr_debug("sbi-state %#x index %d\n", states[i], i);
	}
	if (i != state_count) {
		ret = -ENODEV;
		goto fail;
	}
	if (i != state_count)
		return -ENODEV;

	/* Initialize optional data, used for the hierarchical topology. */
	ret = sbi_dt_cpu_init_topology(drv, data, state_count, cpu);
@@ -277,10 +273,7 @@ static int sbi_cpuidle_dt_init_states(struct device *dev,
	/* Store states in the per-cpu struct. */
	data->states = states;

fail:
	of_node_put(cpu_node);

	return ret;
	return 0;
}

static void sbi_cpuidle_deinit_cpu(int cpu)
@@ -455,7 +448,6 @@ static void sbi_pd_remove(void)

static int sbi_genpd_probe(struct device_node *np)
{
	struct device_node *node;
	int ret = 0, pd_count = 0;

	if (!np)
@@ -465,13 +457,13 @@ static int sbi_genpd_probe(struct device_node *np)
	 * Parse child nodes for the "#power-domain-cells" property and
	 * initialize a genpd/genpd-of-provider pair when it's found.
	 */
	for_each_child_of_node(np, node) {
	for_each_child_of_node_scoped(np, node) {
		if (!of_property_present(node, "#power-domain-cells"))
			continue;

		ret = sbi_pd_init(node);
		if (ret)
			goto put_node;
			goto remove_pd;

		pd_count++;
	}
@@ -487,8 +479,6 @@ static int sbi_genpd_probe(struct device_node *np)

	return 0;

put_node:
	of_node_put(node);
remove_pd:
	sbi_pd_remove();
	pr_err("failed to create CPU PM domains ret=%d\n", ret);
+1 −4
Original line number Diff line number Diff line
@@ -228,10 +228,7 @@ noinstr int cpuidle_enter_state(struct cpuidle_device *dev,
	if (broadcast && tick_broadcast_enter()) {
		index = find_deepest_state(drv, dev, target_state->exit_latency_ns,
					   CPUIDLE_FLAG_TIMER_STOP, false);
		if (index < 0) {
			default_idle_call();
			return -EBUSY;
		}

		target_state = &drv->states[index];
		broadcast = false;
	}
+58 −2
Original line number Diff line number Diff line
@@ -1022,6 +1022,45 @@ static struct cpuidle_state spr_cstates[] __initdata = {
		.enter = NULL }
};

static struct cpuidle_state gnr_cstates[] __initdata = {
	{
		.name = "C1",
		.desc = "MWAIT 0x00",
		.flags = MWAIT2flg(0x00),
		.exit_latency = 1,
		.target_residency = 1,
		.enter = &intel_idle,
		.enter_s2idle = intel_idle_s2idle, },
	{
		.name = "C1E",
		.desc = "MWAIT 0x01",
		.flags = MWAIT2flg(0x01) | CPUIDLE_FLAG_ALWAYS_ENABLE,
		.exit_latency = 4,
		.target_residency = 4,
		.enter = &intel_idle,
		.enter_s2idle = intel_idle_s2idle, },
	{
		.name = "C6",
		.desc = "MWAIT 0x20",
		.flags = MWAIT2flg(0x20) | CPUIDLE_FLAG_TLB_FLUSHED |
					   CPUIDLE_FLAG_INIT_XSTATE,
		.exit_latency = 170,
		.target_residency = 650,
		.enter = &intel_idle,
		.enter_s2idle = intel_idle_s2idle, },
	{
		.name = "C6P",
		.desc = "MWAIT 0x21",
		.flags = MWAIT2flg(0x21) | CPUIDLE_FLAG_TLB_FLUSHED |
					   CPUIDLE_FLAG_INIT_XSTATE,
		.exit_latency = 210,
		.target_residency = 1000,
		.enter = &intel_idle,
		.enter_s2idle = intel_idle_s2idle, },
	{
		.enter = NULL }
};

static struct cpuidle_state atom_cstates[] __initdata = {
	{
		.name = "C1E",
@@ -1453,6 +1492,12 @@ static const struct idle_cpu idle_cpu_spr __initconst = {
	.use_acpi = true,
};

static const struct idle_cpu idle_cpu_gnr __initconst = {
	.state_table = gnr_cstates,
	.disable_promotion_to_c1e = true,
	.use_acpi = true,
};

static const struct idle_cpu idle_cpu_avn __initconst = {
	.state_table = avn_cstates,
	.disable_promotion_to_c1e = true,
@@ -1475,6 +1520,10 @@ static const struct idle_cpu idle_cpu_dnv __initconst = {
	.use_acpi = true,
};

static const struct idle_cpu idle_cpu_tmt __initconst = {
	.disable_promotion_to_c1e = true,
};

static const struct idle_cpu idle_cpu_snr __initconst = {
	.state_table = snr_cstates,
	.disable_promotion_to_c1e = true,
@@ -1533,11 +1582,14 @@ static const struct x86_cpu_id intel_idle_ids[] __initconst = {
	X86_MATCH_VFM(INTEL_ATOM_GRACEMONT,	&idle_cpu_gmt),
	X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X,	&idle_cpu_spr),
	X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X,	&idle_cpu_spr),
	X86_MATCH_VFM(INTEL_GRANITERAPIDS_X,	&idle_cpu_gnr),
	X86_MATCH_VFM(INTEL_XEON_PHI_KNL,	&idle_cpu_knl),
	X86_MATCH_VFM(INTEL_XEON_PHI_KNM,	&idle_cpu_knl),
	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT,	&idle_cpu_bxt),
	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS,	&idle_cpu_bxt),
	X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D,	&idle_cpu_dnv),
	X86_MATCH_VFM(INTEL_ATOM_TREMONT,       &idle_cpu_tmt),
	X86_MATCH_VFM(INTEL_ATOM_TREMONT_L,     &idle_cpu_tmt),
	X86_MATCH_VFM(INTEL_ATOM_TREMONT_D,	&idle_cpu_snr),
	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT,	&idle_cpu_grr),
	X86_MATCH_VFM(INTEL_ATOM_CRESTMONT_X,	&idle_cpu_srf),
@@ -2075,7 +2127,7 @@ static void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv)

	drv->state_count = 1;

	if (icpu)
	if (icpu && icpu->state_table)
		intel_idle_init_cstates_icpu(drv);
	else
		intel_idle_init_cstates_acpi(drv);
@@ -2209,7 +2261,11 @@ static int __init intel_idle_init(void)

	icpu = (const struct idle_cpu *)id->driver_data;
	if (icpu) {
		if (icpu->state_table)
			cpuidle_state_table = icpu->state_table;
		else if (!intel_idle_acpi_cst_extract())
			return -ENODEV;

		auto_demotion_disable_flags = icpu->auto_demotion_disable_flags;
		if (icpu->disable_promotion_to_c1e)
			c1e_promotion = C1E_PROMOTION_DISABLE;
+33 −5
Original line number Diff line number Diff line
@@ -740,7 +740,7 @@ static struct rapl_primitive_info *get_rpi(struct rapl_package *rp, int prim)
{
	struct rapl_primitive_info *rpi = rp->priv->rpi;

	if (prim < 0 || prim > NR_RAPL_PRIMITIVES || !rpi)
	if (prim < 0 || prim >= NR_RAPL_PRIMITIVES || !rpi)
		return NULL;

	return &rpi[prim];
@@ -1267,6 +1267,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
	X86_MATCH_VFM(INTEL_LUNARLAKE_M,	&rapl_defaults_core),
	X86_MATCH_VFM(INTEL_ARROWLAKE_H,	&rapl_defaults_core),
	X86_MATCH_VFM(INTEL_ARROWLAKE,		&rapl_defaults_core),
	X86_MATCH_VFM(INTEL_ARROWLAKE_U,	&rapl_defaults_core),
	X86_MATCH_VFM(INTEL_LAKEFIELD,		&rapl_defaults_core),

	X86_MATCH_VFM(INTEL_ATOM_SILVERMONT,	&rapl_defaults_byt),
@@ -1285,6 +1286,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {

	X86_MATCH_VENDOR_FAM(AMD, 0x17, &rapl_defaults_amd),
	X86_MATCH_VENDOR_FAM(AMD, 0x19, &rapl_defaults_amd),
	X86_MATCH_VENDOR_FAM(AMD, 0x1A, &rapl_defaults_amd),
	X86_MATCH_VENDOR_FAM(HYGON, 0x18, &rapl_defaults_amd),
	{}
};
@@ -2128,6 +2130,21 @@ void rapl_remove_package(struct rapl_package *rp)
}
EXPORT_SYMBOL_GPL(rapl_remove_package);

/*
 * RAPL Package energy counter scope:
 * 1. AMD/HYGON platforms use per-PKG package energy counter
 * 2. For Intel platforms
 *	2.1 CLX-AP platform has per-DIE package energy counter
 *	2.2 Other platforms that uses MSR RAPL are single die systems so the
 *          package energy counter can be considered as per-PKG/per-DIE,
 *          here it is considered as per-DIE.
 *	2.3 New platforms that use TPMI RAPL doesn't care about the
 *	    scope because they are not MSR/CPU based.
 */
#define rapl_msrs_are_pkg_scope()				\
	(boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||	\
	 boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)

/* caller to ensure CPU hotplug lock is held */
struct rapl_package *rapl_find_package_domain_cpuslocked(int id, struct rapl_if_priv *priv,
							 bool id_is_cpu)
@@ -2135,8 +2152,14 @@ struct rapl_package *rapl_find_package_domain_cpuslocked(int id, struct rapl_if_
	struct rapl_package *rp;
	int uid;

	if (id_is_cpu)
		uid = topology_logical_die_id(id);
	if (id_is_cpu) {
		uid = rapl_msrs_are_pkg_scope() ?
		      topology_physical_package_id(id) : topology_logical_die_id(id);
		if (uid < 0) {
			pr_err("topology_logical_(package/die)_id() returned a negative value");
			return NULL;
		}
	}
	else
		uid = id;

@@ -2168,9 +2191,14 @@ struct rapl_package *rapl_add_package_cpuslocked(int id, struct rapl_if_priv *pr
		return ERR_PTR(-ENOMEM);

	if (id_is_cpu) {
		rp->id = topology_logical_die_id(id);
		rp->id = rapl_msrs_are_pkg_scope() ?
			 topology_physical_package_id(id) : topology_logical_die_id(id);
		if ((int)(rp->id) < 0) {
			pr_err("topology_logical_(package/die)_id() returned a negative value");
			return ERR_PTR(-EINVAL);
		}
		rp->lead_cpu = id;
		if (topology_max_dies_per_package() > 1)
		if (!rapl_msrs_are_pkg_scope() && topology_max_dies_per_package() > 1)
			snprintf(rp->name, PACKAGE_DOMAIN_NAME_LENGTH, "package-%d-die-%d",
				 topology_physical_package_id(id), topology_die_id(id));
		else