mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support
@ 2026-11-03 10:14 Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 01/13] dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles Myria Sarvay via B4 Relay
                   ` (13 more replies)
  0 siblings, 14 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay, Nick Chan

This series adds support for the CPU PMU in the new M3, M4 and A18 SoCs
presed in apple devices. These PMUs have new encodings for events, along
with larger codes for these events. All of these events are as Apple
describes them in the various kpep files found under /usr/share/kpep on
macOS 27. More events may exist, but we have no idea of their affinity,
or what they actually count, so we don't include them here.

These patches have been tested on my own M2 (t8133-j413) and M3
(t6031-j514c) devices, as well as by Yuvan on their M4 (t8132-j713)
device.

If possible, the device tree changes should probably go through
apple-soc, as this is where the recently picked up M4 Pro/Max dts are.

Tested-by: Yuvan Shen <yuvanshen09@gmail.com> # on t8132-j713
Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
Myria Sarvay (12):
      dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles
      drivers/perf: apple_m1: Remove unused variables
      drivers/perf: apple_m1: Support per-implementation event size
      drivers/perf: apple_m1: Use macros for per-implementation init functions
      drivers/perf: apple_m1: Add Apple M3 Series Support
      drivers/perf: apple_m1: Add Apple M4 Series Support
      drivers/perf: apple_m1: Add Apple A18 Support
      arm64: dts: apple: t603x: Add PMU Device Nodes
      arm64: dts: apple: t8122: Add PMU Device Nodes
      arm64: dts: apple: t604x: Add PMU Device Nodes
      arm64: dts: apple: t8132: Add PMU Device Nodes
      arm64: dts: apple: t8140: Add PMU Device Nodes

Nick Chan (1):
      drivers/perf: apple_m1: Support per-implementation event tables

 Documentation/devicetree/bindings/arm/pmu.yaml |   8 +
 arch/arm64/boot/dts/apple/t6030.dtsi           |  12 +
 arch/arm64/boot/dts/apple/t6031-base.dtsi      |  12 +
 arch/arm64/boot/dts/apple/t6041.dtsi           |  12 +
 arch/arm64/boot/dts/apple/t8122.dtsi           |  12 +
 arch/arm64/boot/dts/apple/t8132.dtsi           |  12 +
 arch/arm64/boot/dts/apple/t8140.dtsi           |  12 +
 drivers/perf/apple_m1_cpu_pmu.c                | 664 ++++++++++++++++++++++---
 8 files changed, 662 insertions(+), 82 deletions(-)
---
base-commit: acb925da49876e74b806ccd48a7518d2d3368e5d
change-id: 20260929-m3-plus-pmu-events-e4010ab44135

Best regards,
--  
Myria Sarvay <myrialsarvay@gmail.com>



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 01/13] dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-06 12:55   ` Krzysztof Kozlowski
  2026-11-03 10:14 ` [PATCH 02/13] drivers/perf: apple_m1: Remove unused variables Myria Sarvay via B4 Relay
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

Document the compatibles for all current M3, M4 and A18 Pro SoC PMU
variants. Note that the M4+ are split out by chip codenames, instead of
name for the types of cores, as they no longer have individual names for
the performance and efficiency cores.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 Documentation/devicetree/bindings/arm/pmu.yaml | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/Documentation/devicetree/bindings/arm/pmu.yaml b/Documentation/devicetree/bindings/arm/pmu.yaml
index f47baaefcdac..c27f06e82de1 100644
--- a/Documentation/devicetree/bindings/arm/pmu.yaml
+++ b/Documentation/devicetree/bindings/arm/pmu.yaml
@@ -22,8 +22,16 @@ properties:
           - apm,potenza-pmu
           - apple,avalanche-pmu
           - apple,blizzard-pmu
+          - apple,brava-e-pmu
+          - apple,brava-p-pmu
+          - apple,donan-e-pmu
+          - apple,donan-p-pmu
+          - apple,everest-pmu
           - apple,firestorm-pmu
           - apple,icestorm-pmu
+          - apple,sawtooth-pmu
+          - apple,tahiti-e-pmu
+          - apple,tahiti-p-pmu
           - arm,armv8-pmuv3 # Only for s/w models
           - arm,arm1136-pmu
           - arm,arm1176-pmu

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 02/13] drivers/perf: apple_m1: Remove unused variables
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 01/13] dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 03/13] drivers/perf: apple_m1: Support per-implementation event tables Myria Sarvay via B4 Relay
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

These variables are calculated elsewhere as well, remove the extra dead
code.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
Fixes: a639027a1be1 ("drivers/perf: Add Apple icestorm/firestorm CPU PMU driver")
---
 drivers/perf/apple_m1_cpu_pmu.c | 7 -------
 1 file changed, 7 deletions(-)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index 1f73c8a77462..de4026c63afd 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -421,13 +421,6 @@ static void m1_pmu_configure_counter(unsigned int index, unsigned long config_ba
 /* arm_pmu backend */
 static void m1_pmu_enable_event(struct perf_event *event)
 {
-	bool user, kernel;
-	u8 evt;
-
-	evt = event->hw.config_base & M1_PMU_CFG_EVENT;
-	user = event->hw.config_base & M1_PMU_CFG_COUNT_USER;
-	kernel = event->hw.config_base & M1_PMU_CFG_COUNT_KERNEL;
-
 	m1_pmu_configure_counter(event->hw.idx, event->hw.config_base);
 	m1_pmu_enable_counter(event->hw.idx);
 	m1_pmu_enable_counter_interrupt(event->hw.idx);

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 03/13] drivers/perf: apple_m1: Support per-implementation event tables
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 01/13] dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 02/13] drivers/perf: apple_m1: Remove unused variables Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 04/13] drivers/perf: apple_m1: Support per-implementation event size Myria Sarvay via B4 Relay
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay, Nick Chan

From: Nick Chan <towinchenmi@gmail.com>

Use per-implementation event tables to allow supporting implementations
with a different list of events and event affinities.

Signed-off-by: Nick Chan <towinchenmi@gmail.com>
Co-developed-by: Myria Sarvay <myrialsarvay@gmail.com>
Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 drivers/perf/apple_m1_cpu_pmu.c | 113 ++++++++++++++++++++++++----------------
 1 file changed, 69 insertions(+), 44 deletions(-)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index de4026c63afd..2ff0c2e0b737 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -43,9 +43,6 @@
  * moment, we don't really need to distinguish between the two because we
  * know next to nothing about the events themselves, and we already have
  * per cpu-type PMU abstractions.
- *
- * If we eventually find out that the events are different across
- * implementations, we'll have to introduce per cpu-type tables.
  */
 enum m1_pmu_events {
 	M1_PMU_PERFCTR_RETIRE_UOP				= 0x1,
@@ -167,7 +164,7 @@ static const u16 m1_pmu_event_affinity[M1_PMU_PERFCTR_LAST + 1] = {
 	[M1_PMU_PERFCTR_UNKNOWN_fd]				= ONLY_2_4_6,
 };
 
-static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
+static const unsigned int m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 	PERF_MAP_ALL_UNSUPPORTED,
 	[PERF_COUNT_HW_CPU_CYCLES]		= M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE,
 	[PERF_COUNT_HW_INSTRUCTIONS]		= M1_PMU_PERFCTR_INST_ALL,
@@ -486,11 +483,12 @@ static void m1_pmu_write_counter(struct perf_event *event, u64 value)
 	isb();
 }
 
-static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
-				struct perf_event *event)
+static int apple_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+				   struct perf_event *event,
+				   const u16 event_affinities[])
 {
 	unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT;
-	unsigned long affinity = m1_pmu_event_affinity[evtype];
+	unsigned long affinity = event_affinities[evtype];
 	int idx;
 
 	/*
@@ -509,6 +507,12 @@ static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
 	return -EAGAIN;
 }
 
+static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+				struct perf_event *event)
+{
+	return apple_pmu_get_event_idx(cpuc, event, m1_pmu_event_affinity);
+}
+
 static void m1_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
 				   struct perf_event *event)
 {
@@ -536,44 +540,52 @@ static void m1_pmu_stop(struct arm_pmu *cpu_pmu)
 	__m1_pmu_set_mode(PMCR0_IMODE_OFF);
 }
 
+static int apple_pmu_map_event(struct perf_event *event,
+			       const unsigned int (*perf_map)[],
+			       unsigned int flags)
+{
+	event->hw.flags |= flags;
+	return armpmu_map_event(event, perf_map, NULL, M1_PMU_CFG_EVENT);
+}
+
+/*
+ * Apple PMU counters have been observed to be either 48 or
+ * 64 bits wide, depending on the SoC. However, the MSB is
+ * what triggers an overflow interrupt, so we advertise the
+ * counters as being 1-bit smaller than hardware so as to
+ * mimick ARM PMU behaviour
+ */
 static int m1_pmu_map_event(struct perf_event *event)
 {
-	/*
-	 * Although the counters are 48bit wide, bit 47 is what
-	 * triggers the overflow interrupt. Advertise the counters
-	 * being 47bit wide to mimick the behaviour of the ARM PMU.
-	 */
-	event->hw.flags |= ARMPMU_EVT_47BIT;
-	return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT);
+	return apple_pmu_map_event(event, &m1_pmu_perf_map, ARMPMU_EVT_47BIT);
 }
 
 static int m2_pmu_map_event(struct perf_event *event)
 {
-	/*
-	 * Same deal as the above, except that M2 has 64bit counters.
-	 * Which, as far as we're concerned, actually means 63 bits.
-	 * Yes, this is getting awkward.
-	 */
-	event->hw.flags |= ARMPMU_EVT_63BIT;
-	return armpmu_map_event(event, &m1_pmu_perf_map, NULL, M1_PMU_CFG_EVENT);
+	return apple_pmu_map_event(event, &m1_pmu_perf_map, ARMPMU_EVT_63BIT);
 }
 
-static int m1_pmu_map_pmuv3_event(unsigned int eventsel)
+static int apple_pmu_map_pmuv3_event(unsigned int eventsel, const u16 pmceid_map[])
 {
-	u16 m1_event = HW_OP_UNSUPPORTED;
+	u16 apple_event = HW_OP_UNSUPPORTED;
 
 	if (eventsel < ARMV8_PMUV3_MAX_COMMON_EVENTS)
-		m1_event = m1_pmu_pmceid_map[eventsel];
+		apple_event = pmceid_map[eventsel];
 
-	return m1_event == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : m1_event;
+	return apple_event == HW_OP_UNSUPPORTED ? -EOPNOTSUPP : apple_event;
 }
 
-static void m1_pmu_init_pmceid(struct arm_pmu *pmu)
+static int m1_pmu_map_pmuv3_event(unsigned int eventsel)
+{
+	return apple_pmu_map_pmuv3_event(eventsel, m1_pmu_pmceid_map);
+}
+
+static void apple_pmu_init_pmceid(struct arm_pmu *pmu)
 {
 	unsigned int event;
 
 	for (event = 0; event < ARMV8_PMUV3_MAX_COMMON_EVENTS; event++) {
-		if (m1_pmu_map_pmuv3_event(event) >= 0)
+		if (pmu->map_pmuv3_event(event) >= 0)
 			set_bit(event, pmu->pmceid_bitmap);
 	}
 }
@@ -616,33 +628,22 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event,
 	return 0;
 }
 
-static int m1_pmu_init(struct arm_pmu *cpu_pmu, u32 flags)
+static int apple_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->handle_irq	  = m1_pmu_handle_irq;
 	cpu_pmu->enable		  = m1_pmu_enable_event;
 	cpu_pmu->disable	  = m1_pmu_disable_event;
 	cpu_pmu->read_counter	  = m1_pmu_read_counter;
 	cpu_pmu->write_counter	  = m1_pmu_write_counter;
-	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
 	cpu_pmu->clear_event_idx  = m1_pmu_clear_event_idx;
 	cpu_pmu->start		  = m1_pmu_start;
 	cpu_pmu->stop		  = m1_pmu_stop;
-
-	if (flags & ARMPMU_EVT_47BIT)
-		cpu_pmu->map_event = m1_pmu_map_event;
-	else if (flags & ARMPMU_EVT_63BIT)
-		cpu_pmu->map_event = m2_pmu_map_event;
-	else
-		return WARN_ON(-EINVAL);
-
 	cpu_pmu->reset		  = m1_pmu_reset;
 	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
 
-	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
-	m1_pmu_init_pmceid(cpu_pmu);
+	apple_pmu_init_pmceid(cpu_pmu);
 
 	bitmap_set(cpu_pmu->cntr_mask, 0, M1_PMU_NR_COUNTERS);
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
 	return 0;
 }
@@ -651,25 +652,49 @@ static int m1_pmu_init(struct arm_pmu *cpu_pmu, u32 flags)
 static int m1_pmu_ice_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->name = "apple_icestorm_pmu";
-	return m1_pmu_init(cpu_pmu, ARMPMU_EVT_47BIT);
+	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
+	cpu_pmu->map_event	  = m1_pmu_map_event;
+
+	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
+
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	return apple_pmu_init(cpu_pmu);
 }
 
 static int m1_pmu_fire_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->name = "apple_firestorm_pmu";
-	return m1_pmu_init(cpu_pmu, ARMPMU_EVT_47BIT);
+	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
+	cpu_pmu->map_event	  = m1_pmu_map_event;
+
+	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
+
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	return apple_pmu_init(cpu_pmu);
 }
 
 static int m2_pmu_avalanche_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->name = "apple_avalanche_pmu";
-	return m1_pmu_init(cpu_pmu, ARMPMU_EVT_63BIT);
+	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
+	cpu_pmu->map_event	  = m2_pmu_map_event;
+
+	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
+
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	return apple_pmu_init(cpu_pmu);
 }
 
 static int m2_pmu_blizzard_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->name = "apple_blizzard_pmu";
-	return m1_pmu_init(cpu_pmu, ARMPMU_EVT_63BIT);
+	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
+	cpu_pmu->map_event	  = m2_pmu_map_event;
+
+	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
+
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	return apple_pmu_init(cpu_pmu);
 }
 
 static const struct of_device_id m1_pmu_of_device_ids[] = {

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 04/13] drivers/perf: apple_m1: Support per-implementation event size
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (2 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 03/13] drivers/perf: apple_m1: Support per-implementation event tables Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 05/13] drivers/perf: apple_m1: Use macros for per-implementation init functions Myria Sarvay via B4 Relay
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

On M3 and later silicon, events are 16-bits instead of the 8-bits of
earlier implementations.

Co-developed-by: Yuvan Shen <yuvanshen09@gmail.com>
Signed-off-by: Yuvan Shen <yuvanshen09@gmail.com>
Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 drivers/perf/apple_m1_cpu_pmu.c | 54 ++++++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 19 deletions(-)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index 2ff0c2e0b737..a14864263bf1 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -209,10 +209,13 @@ static const struct attribute_group m1_pmu_events_attr_group = {
 	.attrs = m1_pmu_event_attrs,
 };
 
-PMU_FORMAT_ATTR(event, "config:0-7");
+PMU_FORMAT_ATTR_SHOW(event_8b, "config:0-7");
+
+static struct device_attribute format_attr_event_8b =
+	__ATTR(event, 0444, event_8b_show, NULL);
 
 static struct attribute *m1_pmu_format_attrs[] = {
-	&format_attr_event.attr,
+	&format_attr_event_8b.attr,
 	NULL,
 };
 
@@ -373,7 +376,8 @@ static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
 		sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL12, clear, set);
 }
 
-static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
+static void __apple_pmu_configure_eventsel(unsigned int index, u16 event,
+					   unsigned int size, u64 mask)
 {
 	u64 clear = 0, set = 0;
 	int shift;
@@ -388,14 +392,14 @@ static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
 	case 0 ... 1:
 		break;
 	case 2 ... 5:
-		shift = (index - 2) * 8;
-		clear |= (u64)0xff << shift;
+		shift = (index - 2) * size;
+		clear |= mask << shift;
 		set |= (u64)event << shift;
 		sysreg_clear_set_s(SYS_IMP_APL_PMESR0_EL1, clear, set);
 		break;
 	case 6 ... 9:
-		shift = (index - 6) * 8;
-		clear |= (u64)0xff << shift;
+		shift = (index - 6) * size;
+		clear |= mask << shift;
 		set |= (u64)event << shift;
 		sysreg_clear_set_s(SYS_IMP_APL_PMESR1_EL1, clear, set);
 		break;
@@ -412,7 +416,7 @@ static void m1_pmu_configure_counter(unsigned int index, unsigned long config_ba
 
 	__m1_pmu_configure_event_filter(index, user && host, kernel && host, true);
 	__m1_pmu_configure_event_filter(index, user && guest, kernel && guest, false);
-	__m1_pmu_configure_eventsel(index, evt);
+	__apple_pmu_configure_eventsel(index, evt, 8, M1_PMU_CFG_EVENT);
 }
 
 /* arm_pmu backend */
@@ -485,10 +489,8 @@ static void m1_pmu_write_counter(struct perf_event *event, u64 value)
 
 static int apple_pmu_get_event_idx(struct pmu_hw_events *cpuc,
 				   struct perf_event *event,
-				   const u16 event_affinities[])
+				   unsigned long affinity)
 {
-	unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT;
-	unsigned long affinity = event_affinities[evtype];
 	int idx;
 
 	/*
@@ -510,7 +512,10 @@ static int apple_pmu_get_event_idx(struct pmu_hw_events *cpuc,
 static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
 				struct perf_event *event)
 {
-	return apple_pmu_get_event_idx(cpuc, event, m1_pmu_event_affinity);
+	unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT;
+	unsigned long affinity = m1_pmu_event_affinity[evtype];
+
+	return apple_pmu_get_event_idx(cpuc, event, affinity);
 }
 
 static void m1_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
@@ -542,10 +547,10 @@ static void m1_pmu_stop(struct arm_pmu *cpu_pmu)
 
 static int apple_pmu_map_event(struct perf_event *event,
 			       const unsigned int (*perf_map)[],
-			       unsigned int flags)
+			       unsigned int flags, u32 mask)
 {
 	event->hw.flags |= flags;
-	return armpmu_map_event(event, perf_map, NULL, M1_PMU_CFG_EVENT);
+	return armpmu_map_event(event, perf_map, NULL, mask);
 }
 
 /*
@@ -557,12 +562,14 @@ static int apple_pmu_map_event(struct perf_event *event,
  */
 static int m1_pmu_map_event(struct perf_event *event)
 {
-	return apple_pmu_map_event(event, &m1_pmu_perf_map, ARMPMU_EVT_47BIT);
+	return apple_pmu_map_event(event, &m1_pmu_perf_map, ARMPMU_EVT_47BIT,
+				   M1_PMU_CFG_EVENT);
 }
 
 static int m2_pmu_map_event(struct perf_event *event)
 {
-	return apple_pmu_map_event(event, &m1_pmu_perf_map, ARMPMU_EVT_63BIT);
+	return apple_pmu_map_event(event, &m1_pmu_perf_map, ARMPMU_EVT_63BIT,
+				   M1_PMU_CFG_EVENT);
 }
 
 static int apple_pmu_map_pmuv3_event(unsigned int eventsel, const u16 pmceid_map[])
@@ -631,7 +638,6 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event,
 static int apple_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->handle_irq	  = m1_pmu_handle_irq;
-	cpu_pmu->enable		  = m1_pmu_enable_event;
 	cpu_pmu->disable	  = m1_pmu_disable_event;
 	cpu_pmu->read_counter	  = m1_pmu_read_counter;
 	cpu_pmu->write_counter	  = m1_pmu_write_counter;
@@ -639,12 +645,10 @@ static int apple_pmu_init(struct arm_pmu *cpu_pmu)
 	cpu_pmu->start		  = m1_pmu_start;
 	cpu_pmu->stop		  = m1_pmu_stop;
 	cpu_pmu->reset		  = m1_pmu_reset;
-	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
 
 	apple_pmu_init_pmceid(cpu_pmu);
 
 	bitmap_set(cpu_pmu->cntr_mask, 0, M1_PMU_NR_COUNTERS);
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
 	return 0;
 }
 
@@ -652,48 +656,60 @@ static int apple_pmu_init(struct arm_pmu *cpu_pmu)
 static int m1_pmu_ice_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->name = "apple_icestorm_pmu";
+	cpu_pmu->enable		  = m1_pmu_enable_event;
 	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
 	cpu_pmu->map_event	  = m1_pmu_map_event;
+	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
 
 	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
 
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
 	return apple_pmu_init(cpu_pmu);
 }
 
 static int m1_pmu_fire_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->name = "apple_firestorm_pmu";
+	cpu_pmu->enable		  = m1_pmu_enable_event;
 	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
 	cpu_pmu->map_event	  = m1_pmu_map_event;
+	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
 
 	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
 
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
 	return apple_pmu_init(cpu_pmu);
 }
 
 static int m2_pmu_avalanche_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->name = "apple_avalanche_pmu";
+	cpu_pmu->enable		  = m1_pmu_enable_event;
 	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
 	cpu_pmu->map_event	  = m2_pmu_map_event;
+	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
 
 	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
 
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
 	return apple_pmu_init(cpu_pmu);
 }
 
 static int m2_pmu_blizzard_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->name = "apple_blizzard_pmu";
+	cpu_pmu->enable		  = m1_pmu_enable_event;
 	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
 	cpu_pmu->map_event	  = m2_pmu_map_event;
+	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
 
 	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
 
 	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
 	return apple_pmu_init(cpu_pmu);
 }
 

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 05/13] drivers/perf: apple_m1: Use macros for per-implementation init functions
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (3 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 04/13] drivers/perf: apple_m1: Support per-implementation event size Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 06/13] drivers/perf: apple_m1: Add Apple M3 Series Support Myria Sarvay via B4 Relay
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

6 generations of apple silicon, with at least 2 init functions for each
lead to at least 12 init functions. Template them with macros to save
boilterplate code.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 drivers/perf/apple_m1_cpu_pmu.c | 91 ++++++++++++++---------------------------
 1 file changed, 30 insertions(+), 61 deletions(-)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index a14864263bf1..e7e9b51ffadc 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -653,71 +653,40 @@ static int apple_pmu_init(struct arm_pmu *cpu_pmu)
 }
 
 /* Device driver gunk */
-static int m1_pmu_ice_init(struct arm_pmu *cpu_pmu)
-{
-	cpu_pmu->name = "apple_icestorm_pmu";
-	cpu_pmu->enable		  = m1_pmu_enable_event;
-	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
-	cpu_pmu->map_event	  = m1_pmu_map_event;
-	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
-
-	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
-
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
-	return apple_pmu_init(cpu_pmu);
-}
-
-static int m1_pmu_fire_init(struct arm_pmu *cpu_pmu)
-{
-	cpu_pmu->name = "apple_firestorm_pmu";
-	cpu_pmu->enable		  = m1_pmu_enable_event;
-	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
-	cpu_pmu->map_event	  = m1_pmu_map_event;
-	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
-
-	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
-
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
-	return apple_pmu_init(cpu_pmu);
-}
-
-static int m2_pmu_avalanche_init(struct arm_pmu *cpu_pmu)
-{
-	cpu_pmu->name = "apple_avalanche_pmu";
-	cpu_pmu->enable		  = m1_pmu_enable_event;
-	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
-	cpu_pmu->map_event	  = m2_pmu_map_event;
-	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
-
-	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
-
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
-	return apple_pmu_init(cpu_pmu);
-}
-
-static int m2_pmu_blizzard_init(struct arm_pmu *cpu_pmu)
-{
-	cpu_pmu->name = "apple_blizzard_pmu";
-	cpu_pmu->enable		  = m1_pmu_enable_event;
-	cpu_pmu->get_event_idx	  = m1_pmu_get_event_idx;
-	cpu_pmu->map_event	  = m2_pmu_map_event;
-	cpu_pmu->set_event_filter = m1_pmu_set_event_filter;
-
-	cpu_pmu->map_pmuv3_event  = m1_pmu_map_pmuv3_event;
-
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group;
-	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group;
-	return apple_pmu_init(cpu_pmu);
-}
+#define APPLE_PMU_INIT(gen, family)								\
+static int gen ## _pmu_ ## family ## _init(struct arm_pmu *cpu_pmu)				\
+{												\
+	cpu_pmu->name			= "apple_" #family "_pmu";				\
+	cpu_pmu->enable			= gen ## _pmu_enable_event;				\
+	cpu_pmu->get_event_idx		= gen ## _pmu_get_event_idx;				\
+	cpu_pmu->map_event		= gen ## _pmu_map_event;				\
+	cpu_pmu->set_event_filter	= gen ## _pmu_set_event_filter;				\
+												\
+	cpu_pmu->map_pmuv3_event	= gen ## _pmu_map_pmuv3_event;				\
+												\
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &gen ## _pmu_events_attr_group;	\
+	cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &gen ## _pmu_format_attr_group;	\
+	return apple_pmu_init(cpu_pmu);								\
+}
+
+#define m2_pmu_enable_event		m1_pmu_enable_event
+#define m2_pmu_get_event_idx		m1_pmu_get_event_idx
+#define m2_pmu_set_event_filter		m1_pmu_set_event_filter
+#define m2_pmu_map_pmuv3_event		m1_pmu_map_pmuv3_event
+#define m2_pmu_init_pmceid		m1_pmu_init_pmceid
+#define m2_pmu_events_attr_group	m1_pmu_events_attr_group
+#define m2_pmu_format_attr_group	m1_pmu_format_attr_group
+
+APPLE_PMU_INIT(m1, icestorm)
+APPLE_PMU_INIT(m1, firestorm)
+APPLE_PMU_INIT(m2, avalanche)
+APPLE_PMU_INIT(m2, blizzard)
 
 static const struct of_device_id m1_pmu_of_device_ids[] = {
 	{ .compatible = "apple,avalanche-pmu",	.data = m2_pmu_avalanche_init, },
 	{ .compatible = "apple,blizzard-pmu",	.data = m2_pmu_blizzard_init, },
-	{ .compatible = "apple,icestorm-pmu",	.data = m1_pmu_ice_init, },
-	{ .compatible = "apple,firestorm-pmu",	.data = m1_pmu_fire_init, },
+	{ .compatible = "apple,icestorm-pmu",	.data = m1_pmu_icestorm_init, },
+	{ .compatible = "apple,firestorm-pmu",	.data = m1_pmu_firestorm_init, },
 	{ },
 };
 MODULE_DEVICE_TABLE(of, m1_pmu_of_device_ids);

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 06/13] drivers/perf: apple_m1: Add Apple M3 Series Support
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (4 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 05/13] drivers/perf: apple_m1: Use macros for per-implementation init functions Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 07/13] drivers/perf: apple_m1: Add Apple M4 " Myria Sarvay via B4 Relay
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

Add support for the CPU PMU in the M3 Series chips. These events are
encoded with 16 bits, and similar events have different codes when
compared to the M1.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 drivers/perf/apple_m1_cpu_pmu.c | 266 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 263 insertions(+), 3 deletions(-)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index e7e9b51ffadc..ac9373126054 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -22,6 +22,7 @@
 #define M1_PMU_NR_COUNTERS		10
 
 #define M1_PMU_CFG_EVENT		GENMASK(7, 0)
+#define M3_PMU_CFG_EVENT		GENMASK(15, 0)
 
 #define ANY_BUT_0_1			GENMASK(9, 2)
 #define ONLY_2_TO_7			GENMASK(7, 2)
@@ -122,6 +123,84 @@ enum m1_pmu_events {
 	M1_PMU_CFG_COUNT_GUEST					= BIT(11),
 };
 
+enum m3_pmu_events {
+	M3_PMU_PERFCTR_RETIRE_UOP				= 0x1,
+	M3_PMU_PERFCTR_CORE_ACTIVE_CYCLE			= 0x2,
+	M3_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC		= 0x84,
+	M3_PMU_PERFCTR_INST_ALL					= 0x8c,
+	M3_PMU_PERFCTR_INST_BRANCH				= 0x8d,
+	M3_PMU_PERFCTR_INST_BRANCH_CALL				= 0x8e,
+	M3_PMU_PERFCTR_INST_BRANCH_RET				= 0x8f,
+	M3_PMU_PERFCTR_INST_BRANCH_TAKEN			= 0x90,
+	M3_PMU_PERFCTR_INST_BRANCH_INDIR			= 0x93,
+	M3_PMU_PERFCTR_INST_INT_LD				= 0x95,
+	M3_PMU_PERFCTR_INST_INT_ST				= 0x96,
+	M3_PMU_PERFCTR_INST_INT_ALU				= 0x97,
+	M3_PMU_PERFCTR_INST_SIMD_LD				= 0x98,
+	M3_PMU_PERFCTR_INST_SIMD_ST				= 0x99,
+	M3_PMU_PERFCTR_INST_SIMD_ALU				= 0x9a,
+	M3_PMU_PERFCTR_INST_LDST				= 0x9b,
+	M3_PMU_PERFCTR_INST_BARRIER				= 0x9c,
+	M3_PMU_PERFCTR_INST_SIMD_ALU_VEC			= 0x9f,
+	M3_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC		= 0xbf,
+	M3_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC		= 0xc0,
+	M3_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC			= 0xc1,
+	M3_PMU_PERFCTR_ST_MEM_ORDER_VIOL_LD_NONSPEC		= 0xc4,
+	M3_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC		= 0xc5,
+	M3_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC		= 0xc6,
+	M3_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC		= 0xc8,
+	M3_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC	= 0xca,
+	M3_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC			= 0xcb,
+	M3_PMU_PERFCTR_MAP_DISPATCH_BUBBLE_IC			= 0x182,
+	M3_PMU_PERFCTR_MAP_DISPATCH_BUBBLE_ITLB			= 0x183,
+	M3_PMU_PERFCTR_DECODE_UOP				= 0x186,
+	M3_PMU_PERFCTR_L1I_TLB_MISS_DEMAND			= 0x1d4,
+	M3_PMU_PERFCTR_MAP_DISPATCH_BUBBLE			= 0x1d6,
+	M3_PMU_PERFCTR_L1I_CACHE_MISS_DEMAND			= 0x1db,
+	M3_PMU_PERFCTR_FETCH_RESTART				= 0x1de,
+	M3_PMU_PERFCTR_MAP_UOP					= 0x269,
+	M3_PMU_PERFCTR_INTERRUPT_PENDING			= 0x26c,
+	M3_PMU_PERFCTR_MAP_STALL_DISPATCH			= 0x270,
+	M3_PMU_PERFCTR_MAP_REWIND				= 0x275,
+	M3_PMU_PERFCTR_MAP_STALL				= 0x276,
+	M3_PMU_PERFCTR_MAP_INT_UOP				= 0x27c,
+	M3_PMU_PERFCTR_MAP_LDST_UOP				= 0x27d,
+	M3_PMU_PERFCTR_MAP_SIMD_UOP				= 0x27e,
+	M3_PMU_PERFCTR_SCHEDULE_UOP_ANY				= 0x283,
+	M3_PMU_PERFCTR_LDST_UNIT_OLD_L1D_CACHE_MISS		= 0x290,
+	M3_PMU_PERFCTR_LDST_UNIT_WAITING_OLD_L1D_CACHE_MISS	= 0x291,
+	M3_PMU_PERFCTR_SCHEDULE_EMPTY				= 0x351,
+	M3_PMU_PERFCTR_L1I_TLB_FILL				= 0x404,
+	M3_PMU_PERFCTR_L1D_TLB_FILL				= 0x405,
+	M3_PMU_PERFCTR_MMU_TABLE_WALK_INSTRUCTION		= 0x407,
+	M3_PMU_PERFCTR_MMU_TABLE_WALK_DATA			= 0x408,
+	M3_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION			= 0x40a,
+	M3_PMU_PERFCTR_L2_TLB_MISS_DATA				= 0x40b,
+	M3_PMU_PERFCTR_L1D_TLB_ACCESS				= 0x5a0,
+	M3_PMU_PERFCTR_L1D_TLB_MISS				= 0x5a1,
+	M3_PMU_PERFCTR_L1D_CACHE_MISS_ST			= 0x5a2,
+	M3_PMU_PERFCTR_L1D_CACHE_MISS_LD			= 0x5a3,
+	M3_PMU_PERFCTR_LD_UNIT_UOP				= 0x5a6,
+	M3_PMU_PERFCTR_ST_UNIT_UOP				= 0x5a7,
+	M3_PMU_PERFCTR_L1D_CACHE_WRITEBACK			= 0x5a8,
+	M3_PMU_PERFCTR_LDST_X64_UOP				= 0x5b1,
+	M3_PMU_PERFCTR_LDST_XPG_UOP				= 0x5b2,
+	M3_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_SUCC			= 0x5b3,
+	M3_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_FAIL			= 0x5b4,
+	M3_PMU_PERFCTR_ST_NT_UOP				= 0x5e5,
+	M3_PMU_PERFCTR_LD_NT_UOP				= 0x5e6,
+	M3_PMU_PERFCTR_LAST					= M3_PMU_CFG_EVENT,
+
+	/*
+	 * From this point onwards, these are not actual HW events,
+	 * but attributes that get stored in hw->config_base.
+	 */
+	M3_PMU_CFG_COUNT_USER					= BIT(16),
+	M3_PMU_CFG_COUNT_KERNEL					= BIT(17),
+	M3_PMU_CFG_COUNT_HOST					= BIT(18),
+	M3_PMU_CFG_COUNT_GUEST					= BIT(19),
+};
+
 /*
  * Per-event affinity table. Most events can be installed on counter
  * 2-9, but there are a number of exceptions. Note that this table
@@ -164,6 +243,40 @@ static const u16 m1_pmu_event_affinity[M1_PMU_PERFCTR_LAST + 1] = {
 	[M1_PMU_PERFCTR_UNKNOWN_fd]				= ONLY_2_4_6,
 };
 
+struct event_affinity_16 {
+	u16 event_code;
+	u16 affinity;
+};
+
+static const struct event_affinity_16 m3_pmu_event_affinity[] = {
+	{ M3_PMU_PERFCTR_RETIRE_UOP,				BIT(7)			},
+	{ M3_PMU_PERFCTR_CORE_ACTIVE_CYCLE,			ANY_BUT_0_1 | BIT(0)	},
+	{ M3_PMU_PERFCTR_INST_ALL,				BIT(7) | BIT(1)		},
+	{ M3_PMU_PERFCTR_INST_BRANCH,				ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_BRANCH_CALL,			ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_BRANCH_RET,			ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_BRANCH_TAKEN,			ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_BRANCH_INDIR,			ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_INT_LD,				ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_INT_ST,				ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_INT_ALU,				BIT(7)			},
+	{ M3_PMU_PERFCTR_INST_SIMD_LD,				ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_SIMD_ST,				ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_SIMD_ALU,				BIT(7)			},
+	{ M3_PMU_PERFCTR_INST_LDST,				BIT(7)			},
+	{ M3_PMU_PERFCTR_INST_BARRIER,				ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_INST_SIMD_ALU_VEC,			BIT(7)			},
+	{ M3_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC,		ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC,		ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC,			ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_ST_MEM_ORDER_VIOL_LD_NONSPEC,		ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC,		ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC,		ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC,	ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC,	ONLY_5_6_7		},
+	{ M3_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,		ONLY_5_6_7		},
+};
+
 static const unsigned int m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 	PERF_MAP_ALL_UNSUPPORTED,
 	[PERF_COUNT_HW_CPU_CYCLES]		= M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE,
@@ -172,9 +285,20 @@ static const unsigned int m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 	[PERF_COUNT_HW_BRANCH_MISSES]		= M1_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,
 };
 
+static const unsigned int m3_pmu_perf_map[PERF_COUNT_HW_MAX] = {
+	PERF_MAP_ALL_UNSUPPORTED,
+	[PERF_COUNT_HW_CPU_CYCLES]		= M3_PMU_PERFCTR_CORE_ACTIVE_CYCLE,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= M3_PMU_PERFCTR_INST_ALL,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= M3_PMU_PERFCTR_INST_BRANCH,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= M3_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,
+};
+
 #define M1_PMUV3_EVENT_MAP(pmuv3_event, m1_event)				\
 	[ARMV8_PMUV3_PERFCTR_##pmuv3_event]	= M1_PMU_PERFCTR_##m1_event
 
+#define M3_PMUV3_EVENT_MAP(pmuv3_event, m3_event)				\
+	[ARMV8_PMUV3_PERFCTR_##pmuv3_event]	= M3_PMU_PERFCTR_##m3_event
+
 static const u16 m1_pmu_pmceid_map[ARMV8_PMUV3_MAX_COMMON_EVENTS] = {
 	[0 ... ARMV8_PMUV3_MAX_COMMON_EVENTS - 1]	= HW_OP_UNSUPPORTED,
 	M1_PMUV3_EVENT_MAP(INST_RETIRED,	INST_ALL),
@@ -183,6 +307,14 @@ static const u16 m1_pmu_pmceid_map[ARMV8_PMUV3_MAX_COMMON_EVENTS] = {
 	M1_PMUV3_EVENT_MAP(BR_MIS_PRED_RETIRED,	BRANCH_MISPRED_NONSPEC),
 };
 
+static const u16 m3_pmu_pmceid_map[ARMV8_PMUV3_MAX_COMMON_EVENTS] = {
+	[0 ... ARMV8_PMUV3_MAX_COMMON_EVENTS - 1]	= HW_OP_UNSUPPORTED,
+	M3_PMUV3_EVENT_MAP(INST_RETIRED,	INST_ALL),
+	M3_PMUV3_EVENT_MAP(CPU_CYCLES,		CORE_ACTIVE_CYCLE),
+	M3_PMUV3_EVENT_MAP(BR_RETIRED,		INST_BRANCH),
+	M3_PMUV3_EVENT_MAP(BR_MIS_PRED_RETIRED,	BRANCH_MISPRED_NONSPEC),
+};
+
 /* sysfs definitions */
 static ssize_t m1_pmu_events_sysfs_show(struct device *dev,
 					struct device_attribute *attr,
@@ -192,38 +324,76 @@ static ssize_t m1_pmu_events_sysfs_show(struct device *dev,
 
 	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
 
+	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+}
+
+static ssize_t m3_pmu_events_sysfs_show(struct device *dev,
+					struct device_attribute *attr,
+					char *page)
+{
+	struct perf_pmu_events_attr *pmu_attr;
+
+	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
+
 	return sprintf(page, "event=0x%04llx\n", pmu_attr->id);
 }
 
 #define M1_PMU_EVENT_ATTR(name, config)					\
 	PMU_EVENT_ATTR_ID(name, m1_pmu_events_sysfs_show, config)
 
+#define M3_PMU_EVENT_ATTR(name, config)					\
+	PMU_EVENT_ATTR_ID(name, m3_pmu_events_sysfs_show, config)
+
 static struct attribute *m1_pmu_event_attrs[] = {
 	M1_PMU_EVENT_ATTR(cycles, M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE),
 	M1_PMU_EVENT_ATTR(instructions, M1_PMU_PERFCTR_INST_ALL),
 	NULL,
 };
 
+static struct attribute *m3_pmu_event_attrs[] = {
+	M3_PMU_EVENT_ATTR(cycles, M3_PMU_PERFCTR_CORE_ACTIVE_CYCLE),
+	M3_PMU_EVENT_ATTR(instructions, M3_PMU_PERFCTR_INST_ALL),
+	NULL,
+};
+
 static const struct attribute_group m1_pmu_events_attr_group = {
 	.name = "events",
 	.attrs = m1_pmu_event_attrs,
 };
 
+static const struct attribute_group m3_pmu_events_attr_group = {
+	.name = "events",
+	.attrs = m3_pmu_event_attrs,
+};
+
 PMU_FORMAT_ATTR_SHOW(event_8b, "config:0-7");
+PMU_FORMAT_ATTR_SHOW(event_16b, "config:0-15");
 
 static struct device_attribute format_attr_event_8b =
 	__ATTR(event, 0444, event_8b_show, NULL);
+static struct device_attribute format_attr_event_16b =
+	__ATTR(event, 0444, event_16b_show, NULL);
 
 static struct attribute *m1_pmu_format_attrs[] = {
 	&format_attr_event_8b.attr,
 	NULL,
 };
 
+static struct attribute *m3_pmu_format_attrs[] = {
+	&format_attr_event_16b.attr,
+	NULL,
+};
+
 static const struct attribute_group m1_pmu_format_attr_group = {
 	.name = "format",
 	.attrs = m1_pmu_format_attrs,
 };
 
+static const struct attribute_group m3_pmu_format_attr_group = {
+	.name = "format",
+	.attrs = m3_pmu_format_attrs,
+};
+
 /* Low level accessors. No synchronisation. */
 #define PMU_READ_COUNTER(_idx)						\
 	case _idx:	return read_sysreg_s(SYS_IMP_APL_PMC## _idx ##_EL1)
@@ -419,6 +589,19 @@ static void m1_pmu_configure_counter(unsigned int index, unsigned long config_ba
 	__apple_pmu_configure_eventsel(index, evt, 8, M1_PMU_CFG_EVENT);
 }
 
+static void m3_pmu_configure_counter(unsigned int index, unsigned long config_base)
+{
+	bool kernel = config_base & M3_PMU_CFG_COUNT_KERNEL;
+	bool guest = config_base & M3_PMU_CFG_COUNT_GUEST;
+	bool host = config_base & M3_PMU_CFG_COUNT_HOST;
+	bool user = config_base & M3_PMU_CFG_COUNT_USER;
+	u16 evt = config_base & M3_PMU_CFG_EVENT;
+
+	__m1_pmu_configure_event_filter(index, user && host, kernel && host, true);
+	__m1_pmu_configure_event_filter(index, user && guest, kernel && guest, false);
+	__apple_pmu_configure_eventsel(index, evt, 16, M3_PMU_CFG_EVENT);
+}
+
 /* arm_pmu backend */
 static void m1_pmu_enable_event(struct perf_event *event)
 {
@@ -428,6 +611,14 @@ static void m1_pmu_enable_event(struct perf_event *event)
 	isb();
 }
 
+static void m3_pmu_enable_event(struct perf_event *event)
+{
+	m3_pmu_configure_counter(event->hw.idx, event->hw.config_base);
+	m1_pmu_enable_counter(event->hw.idx);
+	m1_pmu_enable_counter_interrupt(event->hw.idx);
+	isb();
+}
+
 static void m1_pmu_disable_event(struct perf_event *event)
 {
 	m1_pmu_disable_counter_interrupt(event->hw.idx);
@@ -509,15 +700,46 @@ static int apple_pmu_get_event_idx(struct pmu_hw_events *cpuc,
 	return -EAGAIN;
 }
 
-static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
-				struct perf_event *event)
+static int apple_pmu_get_event_idx_8(struct pmu_hw_events *cpuc,
+				     struct perf_event *event,
+				     const u16 event_affinities[M1_PMU_CFG_EVENT + 1])
 {
 	unsigned long evtype = event->hw.config_base & M1_PMU_CFG_EVENT;
-	unsigned long affinity = m1_pmu_event_affinity[evtype];
+	unsigned long affinity = event_affinities[evtype];
 
 	return apple_pmu_get_event_idx(cpuc, event, affinity);
 }
 
+static int apple_pmu_get_event_idx_16(struct pmu_hw_events *cpuc,
+				      struct perf_event *event,
+				      unsigned long event_affinities_size,
+				      const struct event_affinity_16 event_affinities[])
+{
+	unsigned long evtype = event->hw.config_base & M3_PMU_CFG_EVENT;
+	unsigned long affinity = ANY_BUT_0_1;
+
+	for (int idx = 0; idx < event_affinities_size; idx++) {
+		if (event_affinities[idx].event_code == evtype) {
+			affinity = event_affinities[idx].affinity;
+			break;
+		}
+	}
+	return apple_pmu_get_event_idx(cpuc, event, affinity);
+}
+
+static int m1_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+				struct perf_event *event)
+{
+	return apple_pmu_get_event_idx_8(cpuc, event, m1_pmu_event_affinity);
+}
+
+static int m3_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+				struct perf_event *event)
+{
+	return apple_pmu_get_event_idx_16(cpuc, event, ARRAY_SIZE(m3_pmu_event_affinity),
+					  m3_pmu_event_affinity);
+}
+
 static void m1_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
 				   struct perf_event *event)
 {
@@ -572,6 +794,12 @@ static int m2_pmu_map_event(struct perf_event *event)
 				   M1_PMU_CFG_EVENT);
 }
 
+static int m3_pmu_map_event(struct perf_event *event)
+{
+	return apple_pmu_map_event(event, &m3_pmu_perf_map, ARMPMU_EVT_63BIT,
+				   M3_PMU_CFG_EVENT);
+}
+
 static int apple_pmu_map_pmuv3_event(unsigned int eventsel, const u16 pmceid_map[])
 {
 	u16 apple_event = HW_OP_UNSUPPORTED;
@@ -587,6 +815,11 @@ static int m1_pmu_map_pmuv3_event(unsigned int eventsel)
 	return apple_pmu_map_pmuv3_event(eventsel, m1_pmu_pmceid_map);
 }
 
+static int m3_pmu_map_pmuv3_event(unsigned int eventsel)
+{
+	return apple_pmu_map_pmuv3_event(eventsel, m3_pmu_pmceid_map);
+}
+
 static void apple_pmu_init_pmceid(struct arm_pmu *pmu)
 {
 	unsigned int event;
@@ -635,6 +868,29 @@ static int m1_pmu_set_event_filter(struct hw_perf_event *event,
 	return 0;
 }
 
+static int m3_pmu_set_event_filter(struct hw_perf_event *event,
+				   struct perf_event_attr *attr)
+{
+	unsigned long config_base = 0;
+
+	if (!attr->exclude_guest && !is_kernel_in_hyp_mode()) {
+		pr_debug("ARM performance counters do not support mode exclusion\n");
+		return -EOPNOTSUPP;
+	}
+	if (!attr->exclude_kernel)
+		config_base |= M3_PMU_CFG_COUNT_KERNEL;
+	if (!attr->exclude_user)
+		config_base |= M3_PMU_CFG_COUNT_USER;
+	if (!attr->exclude_host)
+		config_base |= M3_PMU_CFG_COUNT_HOST;
+	if (!attr->exclude_guest)
+		config_base |= M3_PMU_CFG_COUNT_GUEST;
+
+	event->config_base = config_base;
+
+	return 0;
+}
+
 static int apple_pmu_init(struct arm_pmu *cpu_pmu)
 {
 	cpu_pmu->handle_irq	  = m1_pmu_handle_irq;
@@ -681,8 +937,12 @@ APPLE_PMU_INIT(m1, icestorm)
 APPLE_PMU_INIT(m1, firestorm)
 APPLE_PMU_INIT(m2, avalanche)
 APPLE_PMU_INIT(m2, blizzard)
+APPLE_PMU_INIT(m3, sawtooth)
+APPLE_PMU_INIT(m3, everest)
 
 static const struct of_device_id m1_pmu_of_device_ids[] = {
+	{ .compatible = "apple,sawtooth-pmu",	.data = m3_pmu_sawtooth_init, },
+	{ .compatible = "apple,everest-pmu",	.data = m3_pmu_everest_init, },
 	{ .compatible = "apple,avalanche-pmu",	.data = m2_pmu_avalanche_init, },
 	{ .compatible = "apple,blizzard-pmu",	.data = m2_pmu_blizzard_init, },
 	{ .compatible = "apple,icestorm-pmu",	.data = m1_pmu_icestorm_init, },

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 07/13] drivers/perf: apple_m1: Add Apple M4 Series Support
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (5 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 06/13] drivers/perf: apple_m1: Add Apple M3 Series Support Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 08/13] drivers/perf: apple_m1: Add Apple A18 Support Myria Sarvay via B4 Relay
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

Add support for the CPU PMU found in the various M4 SoCs. This PMU is
almost exactly the same as the M3 PMU, just with different event
encodings.

One notable difference, is the addition of the various ARM_* events,
which appear to implement the PMUv3 specific events that the arm PMU
specification provides. Hook them up with the various perf events so
that more can easily be counted on M4+ devices.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 drivers/perf/apple_m1_cpu_pmu.c | 224 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 224 insertions(+)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index ac9373126054..bdbd138cf1db 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -201,6 +201,121 @@ enum m3_pmu_events {
 	M3_PMU_CFG_COUNT_GUEST					= BIT(19),
 };
 
+enum m4_pmu_events {
+	M4_PMU_PERFCTR_ARM_L1D_CACHE_REFILL				= 0x03,
+	M4_PMU_PERFCTR_ARM_L1D_CACHE					= 0x04,
+	M4_PMU_PERFCTR_INST_ALL						= 0x08,
+	M4_PMU_PERFCTR_ARM_BR_MIS_PRED					= 0x10,
+	M4_PMU_PERFCTR_CORE_ACTIVE_CYCLE				= 0x11,
+	M4_PMU_PERFCTR_ARM_BR_PRED					= 0x12,
+	M4_PMU_PERFCTR_INST_BRANCH					= 0x21,
+	M4_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC				= 0x22,
+	M4_PMU_PERFCTR_ARM_STALL_FRONTEND				= 0x23,
+	M4_PMU_PERFCTR_ARM_STALL_BACKEND				= 0x24,
+	M4_PMU_PERFCTR_ARM_L1D_CACHE_LMISS_RD				= 0x39,
+	M4_PMU_PERFCTR_RETIRE_UOP					= 0x3a,
+	M4_PMU_PERFCTR_MAP_UOP						= 0x3b,
+	M4_PMU_PERFCTR_ARM_STALL					= 0x3c,
+	M4_PMU_PERFCTR_ARM_STALL_SLOT_BACKEND				= 0x3d,
+	M4_PMU_PERFCTR_ARM_STALL_SLOT_FRONTEND				= 0x3e,
+	M4_PMU_PERFCTR_ARM_STALL_SLOT					= 0x3f,
+	M4_PMU_PERFCTR_ARM_L1D_CACHE_RD					= 0x40,
+	M4_PMU_PERFCTR_MAP_DISPATCH_BUBBLE_IC				= 0x182,
+	M4_PMU_PERFCTR_MAP_DISPATCH_BUBBLE_ITLB				= 0x183,
+	M4_PMU_PERFCTR_DECODE_UOP					= 0x186,
+	M4_PMU_PERFCTR_L1I_TLB_MISS_DEMAND				= 0x1d4,
+	M4_PMU_PERFCTR_MAP_DISPATCH_BUBBLE				= 0x1d6,
+	M4_PMU_PERFCTR_FETCH_RESTART					= 0x1de,
+	M4_PMU_PERFCTR_MAP_DISPATCH_BUBBLE_SLOT				= 0x1e1,
+	M4_PMU_PERFCTR_INTERRUPT_PENDING				= 0x26c,
+	M4_PMU_PERFCTR_MAP_STALL_DISPATCH				= 0x270,
+	M4_PMU_PERFCTR_MAP_REWIND					= 0x275,
+	M4_PMU_PERFCTR_MAP_STALL					= 0x276,
+	M4_PMU_PERFCTR_MAP_INT_UOP					= 0x27c,
+	M4_PMU_PERFCTR_MAP_LDST_UOP					= 0x27d,
+	M4_PMU_PERFCTR_MAP_SIMD_UOP					= 0x27e,
+	M4_PMU_PERFCTR_SCHEDULE_UOP_ANY					= 0x283,
+	M4_PMU_PERFCTR_MAP_INT_SME_UOP					= 0x285,
+	M4_PMU_PERFCTR_SME_ENGINE_SM_ENABLE				= 0x286,
+	M4_PMU_PERFCTR_SME_ENGINE_SM_ZA_ENABLE				= 0x287,
+	M4_PMU_PERFCTR_SME_ENGINE_ZA_ENABLED_SM_DISABLED		= 0x288,
+	M4_PMU_PERFCTR_LDST_UNIT_WAITING_SME_ENGINE_INST_QUEUE_FULL	= 0x28c,
+	M4_PMU_PERFCTR_SCHEDULE_WAITING_SME_ENGINE_REG_DATA		= 0x28e,
+	M4_PMU_PERFCTR_LDST_UNIT_WAITING_SME_ENGINE_MEM_DATA		= 0x28f,
+	M4_PMU_PERFCTR_LDST_UNIT_OLD_L1D_CACHE_MISS			= 0x290,
+	M4_PMU_PERFCTR_LDST_UNIT_WAITING_OLD_L1D_CACHE_MISS		= 0x291,
+	M4_PMU_PERFCTR_LD_UNIT_WAITING_YOUNG_L1D_CACHE_MISS		= 0x294,
+	M4_PMU_PERFCTR_MAP_RECOVERY					= 0x2ad,
+	M4_PMU_PERFCTR_MAP_STALL_NONRECOVERY				= 0x2ae,
+	M4_PMU_PERFCTR_SCHEDULE_EMPTY					= 0x351,
+	M4_PMU_PERFCTR_L1I_TLB_FILL					= 0x404,
+	M4_PMU_PERFCTR_L1D_TLB_FILL					= 0x405,
+	M4_PMU_PERFCTR_MMU_TABLE_WALK_INSTRUCTION			= 0x407,
+	M4_PMU_PERFCTR_MMU_TABLE_WALK_DATA				= 0x408,
+	M4_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION				= 0x40a,
+	M4_PMU_PERFCTR_L2_TLB_MISS_DATA					= 0x40b,
+	M4_PMU_PERFCTR_LDST_SME_XPG_UOP					= 0x508,
+	M4_PMU_PERFCTR_INST_SME_ENGINE_PACKING_FUSED			= 0x529,
+	M4_PMU_PERFCTR_LD_BLOCKED_BY_SME_LDST				= 0x52c,
+	M4_PMU_PERFCTR_ST_BARRIER_BLOCKED_BY_SME_LDST			= 0x52e,
+	M4_PMU_PERFCTR_LD_SME_NT_UOP					= 0x573,
+	M4_PMU_PERFCTR_ST_SME_NT_UOP					= 0x574,
+	M4_PMU_PERFCTR_LD_SME_NORMAL_UOP				= 0x575,
+	M4_PMU_PERFCTR_ST_SME_NORMAL_UOP				= 0x576,
+	M4_PMU_PERFCTR_LDST_SME_PRED_INACTIVE				= 0x577,
+	M4_PMU_PERFCTR_L1D_TLB_ACCESS					= 0x5a0,
+	M4_PMU_PERFCTR_L1D_TLB_MISS					= 0x5a1,
+	M4_PMU_PERFCTR_L1D_CACHE_MISS_ST				= 0x5a2,
+	M4_PMU_PERFCTR_L1D_CACHE_MISS_LD				= 0x5a3,
+	M4_PMU_PERFCTR_LD_UNIT_UOP					= 0x5a6,
+	M4_PMU_PERFCTR_ST_UNIT_UOP					= 0x5a7,
+	M4_PMU_PERFCTR_L1D_CACHE_WRITEBACK				= 0x5a8,
+	M4_PMU_PERFCTR_LDST_X64_UOP					= 0x5b1,
+	M4_PMU_PERFCTR_LDST_XPG_UOP					= 0x5b2,
+	M4_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_SUCC				= 0x5b3,
+	M4_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_FAIL				= 0x5b4,
+	M4_PMU_PERFCTR_ST_NT_UOP					= 0x5e5,
+	M4_PMU_PERFCTR_LD_NT_UOP					= 0x5e6,
+	M4_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC			= 0x884,
+	M4_PMU_PERFCTR_INST_BRANCH_CALL					= 0x88e,
+	M4_PMU_PERFCTR_INST_BRANCH_RET					= 0x88f,
+	M4_PMU_PERFCTR_INST_BRANCH_TAKEN				= 0x890,
+	M4_PMU_PERFCTR_INST_BRANCH_INDIR				= 0x893,
+	M4_PMU_PERFCTR_INST_BRANCH_COND					= 0x894,
+	M4_PMU_PERFCTR_INST_INT_LD					= 0x895,
+	M4_PMU_PERFCTR_INST_INT_ST					= 0x896,
+	M4_PMU_PERFCTR_INST_INT_ALU					= 0x897,
+	M4_PMU_PERFCTR_INST_SIMD_LD					= 0x898,
+	M4_PMU_PERFCTR_INST_SIMD_ST					= 0x899,
+	M4_PMU_PERFCTR_INST_SIMD_ALU					= 0x89a,
+	M4_PMU_PERFCTR_INST_LDST					= 0x89b,
+	M4_PMU_PERFCTR_INST_BARRIER					= 0x89c,
+	M4_PMU_PERFCTR_INST_SIMD_ALU_VEC				= 0x89f,
+	M4_PMU_PERFCTR_INST_SME_ENGINE_SCALARFP				= 0x8a0,
+	M4_PMU_PERFCTR_INST_SME_ENGINE_LD				= 0x8a1,
+	M4_PMU_PERFCTR_INST_SME_ENGINE_ST				= 0x8a2,
+	M4_PMU_PERFCTR_INST_SME_ENGINE_ALU				= 0x8a3,
+	M4_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC			= 0x8bf,
+	M4_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC			= 0x8c0,
+	M4_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC				= 0x8c1,
+	M4_PMU_PERFCTR_ST_MEM_ORDER_VIOL_LD_NONSPEC			= 0x8c4,
+	M4_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC			= 0x8c5,
+	M4_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC			= 0x8c6,
+	M4_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC			= 0x8c8,
+	M4_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC		= 0x8ca,
+	M4_PMU_PERFCTR_L1I_CACHE_MISS_DEMAND				= 0x4006,
+	M4_PMU_PERFCTR_LAST						= M3_PMU_CFG_EVENT,
+
+	/*
+	 * From this point onwards, these are not actual HW events,
+	 * but attributes that get stored in hw->config_base.
+	 */
+	M4_PMU_CFG_COUNT_USER						= BIT(16),
+	M4_PMU_CFG_COUNT_KERNEL						= BIT(17),
+	M4_PMU_CFG_COUNT_HOST						= BIT(18),
+	M4_PMU_CFG_COUNT_GUEST						= BIT(19),
+};
+
 /*
  * Per-event affinity table. Most events can be installed on counter
  * 2-9, but there are a number of exceptions. Note that this table
@@ -277,6 +392,40 @@ static const struct event_affinity_16 m3_pmu_event_affinity[] = {
 	{ M3_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,		ONLY_5_6_7		},
 };
 
+static const struct event_affinity_16 m4_pmu_event_affinity[] = {
+	{ M4_PMU_PERFCTR_INST_ALL,				ONLY_2_TO_7 | BIT(1)	},
+	{ M4_PMU_PERFCTR_CORE_ACTIVE_CYCLE,			ANY_BUT_0_1 | BIT(0)	},
+	{ M4_PMU_PERFCTR_INST_BRANCH,				ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,		ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_RETIRE_UOP,				ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_BRANCH_CALL,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_BRANCH_RET,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_BRANCH_TAKEN,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_BRANCH_INDIR,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_BRANCH_COND,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_INT_LD,				ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_INT_ST,				ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_INT_ALU,				BIT(7)			},
+	{ M4_PMU_PERFCTR_INST_SIMD_LD,				ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_SIMD_ST,				ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_SIMD_ALU,				BIT(7)			},
+	{ M4_PMU_PERFCTR_INST_LDST,				BIT(7)			},
+	{ M4_PMU_PERFCTR_INST_BARRIER,				ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_SIMD_ALU_VEC,			BIT(7)			},
+	{ M4_PMU_PERFCTR_INST_SME_ENGINE_SCALARFP,		ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_SME_ENGINE_LD,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_SME_ENGINE_ST,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_INST_SME_ENGINE_ALU,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC,		ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC,		ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC,			ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_ST_MEM_ORDER_VIOL_LD_NONSPEC,		ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC,		ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC,		ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC,	ONLY_2_TO_7		},
+	{ M4_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC,	ONLY_2_TO_7		},
+};
+
 static const unsigned int m1_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 	PERF_MAP_ALL_UNSUPPORTED,
 	[PERF_COUNT_HW_CPU_CYCLES]		= M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE,
@@ -293,12 +442,27 @@ static const unsigned int m3_pmu_perf_map[PERF_COUNT_HW_MAX] = {
 	[PERF_COUNT_HW_BRANCH_MISSES]		= M3_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC,
 };
 
+static const unsigned int m4_pmu_perf_map[PERF_COUNT_HW_MAX] = {
+	PERF_MAP_ALL_UNSUPPORTED,
+	[PERF_COUNT_HW_CPU_CYCLES]		= M4_PMU_PERFCTR_CORE_ACTIVE_CYCLE,
+	[PERF_COUNT_HW_INSTRUCTIONS]		= M4_PMU_PERFCTR_INST_ALL,
+	[PERF_COUNT_HW_CACHE_REFERENCES]	= M4_PMU_PERFCTR_ARM_L1D_CACHE,
+	[PERF_COUNT_HW_CACHE_MISSES]		= M4_PMU_PERFCTR_ARM_L1D_CACHE_REFILL,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS]	= M4_PMU_PERFCTR_INST_BRANCH,
+	[PERF_COUNT_HW_BRANCH_MISSES]		= M4_PMU_PERFCTR_ARM_BR_MIS_PRED,
+	[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND]	= M4_PMU_PERFCTR_ARM_STALL_FRONTEND,
+	[PERF_COUNT_HW_STALLED_CYCLES_BACKEND]	= M4_PMU_PERFCTR_ARM_STALL_BACKEND,
+};
+
 #define M1_PMUV3_EVENT_MAP(pmuv3_event, m1_event)				\
 	[ARMV8_PMUV3_PERFCTR_##pmuv3_event]	= M1_PMU_PERFCTR_##m1_event
 
 #define M3_PMUV3_EVENT_MAP(pmuv3_event, m3_event)				\
 	[ARMV8_PMUV3_PERFCTR_##pmuv3_event]	= M3_PMU_PERFCTR_##m3_event
 
+#define M4_PMUV3_EVENT_MAP(pmuv3_event, m4_event)				\
+	[ARMV8_PMUV3_PERFCTR_##pmuv3_event]	= M4_PMU_PERFCTR_##m4_event
+
 static const u16 m1_pmu_pmceid_map[ARMV8_PMUV3_MAX_COMMON_EVENTS] = {
 	[0 ... ARMV8_PMUV3_MAX_COMMON_EVENTS - 1]	= HW_OP_UNSUPPORTED,
 	M1_PMUV3_EVENT_MAP(INST_RETIRED,	INST_ALL),
@@ -315,6 +479,25 @@ static const u16 m3_pmu_pmceid_map[ARMV8_PMUV3_MAX_COMMON_EVENTS] = {
 	M3_PMUV3_EVENT_MAP(BR_MIS_PRED_RETIRED,	BRANCH_MISPRED_NONSPEC),
 };
 
+static const u16 m4_pmu_pmceid_map[ARMV8_PMUV3_MAX_COMMON_EVENTS] = {
+	[0 ... ARMV8_PMUV3_MAX_COMMON_EVENTS - 1]	= HW_OP_UNSUPPORTED,
+	M4_PMUV3_EVENT_MAP(L1D_CACHE_REFILL,	ARM_L1D_CACHE_REFILL),
+	M4_PMUV3_EVENT_MAP(L1D_CACHE,		ARM_L1D_CACHE),
+	M4_PMUV3_EVENT_MAP(INST_RETIRED,	INST_ALL),
+	M4_PMUV3_EVENT_MAP(BR_MIS_PRED,		ARM_BR_MIS_PRED),
+	M4_PMUV3_EVENT_MAP(CPU_CYCLES,		CORE_ACTIVE_CYCLE),
+	M4_PMUV3_EVENT_MAP(BR_PRED,		ARM_BR_PRED),
+	M4_PMUV3_EVENT_MAP(BR_RETIRED,		INST_BRANCH),
+	M4_PMUV3_EVENT_MAP(STALL_FRONTEND,	ARM_STALL_FRONTEND),
+	M4_PMUV3_EVENT_MAP(STALL_BACKEND,	ARM_STALL_BACKEND),
+	M4_PMUV3_EVENT_MAP(L1D_CACHE_LMISS_RD,	ARM_L1D_CACHE_LMISS_RD),
+	M4_PMUV3_EVENT_MAP(STALL,		ARM_STALL),
+	M4_PMUV3_EVENT_MAP(STALL_SLOT_BACKEND,	ARM_STALL_SLOT_BACKEND),
+	M4_PMUV3_EVENT_MAP(STALL_SLOT_FRONTEND,	ARM_STALL_SLOT_FRONTEND),
+	M4_PMUV3_EVENT_MAP(STALL_SLOT,		ARM_STALL_SLOT),
+	M4_PMUV3_EVENT_MAP(BR_MIS_PRED_RETIRED,	BRANCH_MISPRED_NONSPEC),
+};
+
 /* sysfs definitions */
 static ssize_t m1_pmu_events_sysfs_show(struct device *dev,
 					struct device_attribute *attr,
@@ -356,6 +539,12 @@ static struct attribute *m3_pmu_event_attrs[] = {
 	NULL,
 };
 
+static struct attribute *m4_pmu_event_attrs[] = {
+	M3_PMU_EVENT_ATTR(cycles, M4_PMU_PERFCTR_CORE_ACTIVE_CYCLE),
+	M3_PMU_EVENT_ATTR(instructions, M4_PMU_PERFCTR_INST_ALL),
+	NULL,
+};
+
 static const struct attribute_group m1_pmu_events_attr_group = {
 	.name = "events",
 	.attrs = m1_pmu_event_attrs,
@@ -366,6 +555,11 @@ static const struct attribute_group m3_pmu_events_attr_group = {
 	.attrs = m3_pmu_event_attrs,
 };
 
+static const struct attribute_group m4_pmu_events_attr_group = {
+	.name = "events",
+	.attrs = m4_pmu_event_attrs,
+};
+
 PMU_FORMAT_ATTR_SHOW(event_8b, "config:0-7");
 PMU_FORMAT_ATTR_SHOW(event_16b, "config:0-15");
 
@@ -740,6 +934,13 @@ static int m3_pmu_get_event_idx(struct pmu_hw_events *cpuc,
 					  m3_pmu_event_affinity);
 }
 
+static int m4_pmu_get_event_idx(struct pmu_hw_events *cpuc,
+				struct perf_event *event)
+{
+	return apple_pmu_get_event_idx_16(cpuc, event, ARRAY_SIZE(m4_pmu_event_affinity),
+					  m4_pmu_event_affinity);
+}
+
 static void m1_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
 				   struct perf_event *event)
 {
@@ -800,6 +1001,12 @@ static int m3_pmu_map_event(struct perf_event *event)
 				   M3_PMU_CFG_EVENT);
 }
 
+static int m4_pmu_map_event(struct perf_event *event)
+{
+	return apple_pmu_map_event(event, &m4_pmu_perf_map, ARMPMU_EVT_63BIT,
+				   M3_PMU_CFG_EVENT);
+}
+
 static int apple_pmu_map_pmuv3_event(unsigned int eventsel, const u16 pmceid_map[])
 {
 	u16 apple_event = HW_OP_UNSUPPORTED;
@@ -820,6 +1027,11 @@ static int m3_pmu_map_pmuv3_event(unsigned int eventsel)
 	return apple_pmu_map_pmuv3_event(eventsel, m3_pmu_pmceid_map);
 }
 
+static int m4_pmu_map_pmuv3_event(unsigned int eventsel)
+{
+	return apple_pmu_map_pmuv3_event(eventsel, m4_pmu_pmceid_map);
+}
+
 static void apple_pmu_init_pmceid(struct arm_pmu *pmu)
 {
 	unsigned int event;
@@ -933,14 +1145,26 @@ static int gen ## _pmu_ ## family ## _init(struct arm_pmu *cpu_pmu)				\
 #define m2_pmu_events_attr_group	m1_pmu_events_attr_group
 #define m2_pmu_format_attr_group	m1_pmu_format_attr_group
 
+#define m4_pmu_enable_event		m3_pmu_enable_event
+#define m4_pmu_set_event_filter		m3_pmu_set_event_filter
+#define m4_pmu_format_attr_group	m3_pmu_format_attr_group
+
 APPLE_PMU_INIT(m1, icestorm)
 APPLE_PMU_INIT(m1, firestorm)
 APPLE_PMU_INIT(m2, avalanche)
 APPLE_PMU_INIT(m2, blizzard)
 APPLE_PMU_INIT(m3, sawtooth)
 APPLE_PMU_INIT(m3, everest)
+APPLE_PMU_INIT(m4, donan_e)
+APPLE_PMU_INIT(m4, donan_p)
+APPLE_PMU_INIT(m4, brava_e)
+APPLE_PMU_INIT(m4, brava_p)
 
 static const struct of_device_id m1_pmu_of_device_ids[] = {
+	{ .compatible = "apple,brava-e-pmu",	.data = m4_pmu_brava_e_init, },
+	{ .compatible = "apple,brava-p-pmu",	.data = m4_pmu_brava_p_init, },
+	{ .compatible = "apple,donan-e-pmu",	.data = m4_pmu_donan_e_init, },
+	{ .compatible = "apple,donan-p-pmu",	.data = m4_pmu_donan_p_init, },
 	{ .compatible = "apple,sawtooth-pmu",	.data = m3_pmu_sawtooth_init, },
 	{ .compatible = "apple,everest-pmu",	.data = m3_pmu_everest_init, },
 	{ .compatible = "apple,avalanche-pmu",	.data = m2_pmu_avalanche_init, },

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 08/13] drivers/perf: apple_m1: Add Apple A18 Support
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (6 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 07/13] drivers/perf: apple_m1: Add Apple M4 " Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 09/13] arm64: dts: apple: t603x: Add PMU Device Nodes Myria Sarvay via B4 Relay
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

The A18 has events and affinities identical to the M4, so use it.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 drivers/perf/apple_m1_cpu_pmu.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/drivers/perf/apple_m1_cpu_pmu.c b/drivers/perf/apple_m1_cpu_pmu.c
index bdbd138cf1db..775f3d5aba7e 100644
--- a/drivers/perf/apple_m1_cpu_pmu.c
+++ b/drivers/perf/apple_m1_cpu_pmu.c
@@ -1149,12 +1149,23 @@ static int gen ## _pmu_ ## family ## _init(struct arm_pmu *cpu_pmu)				\
 #define m4_pmu_set_event_filter		m3_pmu_set_event_filter
 #define m4_pmu_format_attr_group	m3_pmu_format_attr_group
 
+#define a18_pmu_enable_event		m4_pmu_enable_event
+#define a18_pmu_map_event		m4_pmu_map_event
+#define a18_pmu_get_event_idx		m4_pmu_get_event_idx
+#define a18_pmu_set_event_filter	m4_pmu_set_event_filter
+#define a18_pmu_map_pmuv3_event		m4_pmu_map_pmuv3_event
+#define a18_pmu_init_pmceid		m4_pmu_init_pmceid
+#define a18_pmu_events_attr_group	m4_pmu_events_attr_group
+#define a18_pmu_format_attr_group	m4_pmu_format_attr_group
+
 APPLE_PMU_INIT(m1, icestorm)
 APPLE_PMU_INIT(m1, firestorm)
 APPLE_PMU_INIT(m2, avalanche)
 APPLE_PMU_INIT(m2, blizzard)
 APPLE_PMU_INIT(m3, sawtooth)
 APPLE_PMU_INIT(m3, everest)
+APPLE_PMU_INIT(a18, tahiti_e)
+APPLE_PMU_INIT(a18, tahiti_p)
 APPLE_PMU_INIT(m4, donan_e)
 APPLE_PMU_INIT(m4, donan_p)
 APPLE_PMU_INIT(m4, brava_e)
@@ -1165,6 +1176,8 @@ static const struct of_device_id m1_pmu_of_device_ids[] = {
 	{ .compatible = "apple,brava-p-pmu",	.data = m4_pmu_brava_p_init, },
 	{ .compatible = "apple,donan-e-pmu",	.data = m4_pmu_donan_e_init, },
 	{ .compatible = "apple,donan-p-pmu",	.data = m4_pmu_donan_p_init, },
+	{ .compatible = "apple,tahiti-e-pmu",	.data = a18_pmu_tahiti_e_init, },
+	{ .compatible = "apple,tahiti-p-pmu",	.data = a18_pmu_tahiti_p_init, },
 	{ .compatible = "apple,sawtooth-pmu",	.data = m3_pmu_sawtooth_init, },
 	{ .compatible = "apple,everest-pmu",	.data = m3_pmu_everest_init, },
 	{ .compatible = "apple,avalanche-pmu",	.data = m2_pmu_avalanche_init, },

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 09/13] arm64: dts: apple: t603x: Add PMU Device Nodes
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (7 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 08/13] drivers/perf: apple_m1: Add Apple A18 Support Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 10/13] arm64: dts: apple: t8122: " Myria Sarvay via B4 Relay
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

Adds the PMU nodes to all t603x devices.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 arch/arm64/boot/dts/apple/t6030.dtsi      | 12 ++++++++++++
 arch/arm64/boot/dts/apple/t6031-base.dtsi | 12 ++++++++++++
 2 files changed, 24 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t6030.dtsi b/arch/arm64/boot/dts/apple/t6030.dtsi
index 85a16d03e22f..c3779e1584c2 100644
--- a/arch/arm64/boot/dts/apple/t6030.dtsi
+++ b/arch/arm64/boot/dts/apple/t6030.dtsi
@@ -239,6 +239,18 @@ l2_cache_1: l2-cache-1 {
 		};
 	};
 
+	pmu-e {
+		compatible = "apple,sawtooth-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pmu-p {
+		compatible = "apple,everest-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	reserved-memory {
 		ranges;
 		#address-cells = <2>;
diff --git a/arch/arm64/boot/dts/apple/t6031-base.dtsi b/arch/arm64/boot/dts/apple/t6031-base.dtsi
index f62ce0690182..3b97c1240934 100644
--- a/arch/arm64/boot/dts/apple/t6031-base.dtsi
+++ b/arch/arm64/boot/dts/apple/t6031-base.dtsi
@@ -308,6 +308,18 @@ l2_cache_2: l2-cache-2 {
 		};
 	};
 
+	pmu-e {
+		compatible = "apple,sawtooth-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ 0 AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pmu-p {
+		compatible = "apple,everest-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ 0 AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	reserved-memory {
 		ranges;
 		#address-cells = <2>;

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 10/13] arm64: dts: apple: t8122: Add PMU Device Nodes
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (8 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 09/13] arm64: dts: apple: t603x: Add PMU Device Nodes Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 11/13] arm64: dts: apple: t604x: " Myria Sarvay via B4 Relay
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

Adds the PMU nodes to all t8122 devices.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 arch/arm64/boot/dts/apple/t8122.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8122.dtsi b/arch/arm64/boot/dts/apple/t8122.dtsi
index 959ddf36efa1..c9e81a6cc9b7 100644
--- a/arch/arm64/boot/dts/apple/t8122.dtsi
+++ b/arch/arm64/boot/dts/apple/t8122.dtsi
@@ -180,6 +180,18 @@ l2_cache_1: l2-cache-1 {
 		};
 	};
 
+	pmu-e {
+		compatible = "apple,sawtooth-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pmu-p {
+		compatible = "apple,everest-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	soc {
 		compatible = "simple-bus";
 		ranges;

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 11/13] arm64: dts: apple: t604x: Add PMU Device Nodes
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (9 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 10/13] arm64: dts: apple: t8122: " Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 12/13] arm64: dts: apple: t8132: " Myria Sarvay via B4 Relay
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

Adds the PMU nodes to all t604x devices.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 arch/arm64/boot/dts/apple/t6041.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t6041.dtsi b/arch/arm64/boot/dts/apple/t6041.dtsi
index 9110d05c896d..2c72972d1219 100644
--- a/arch/arm64/boot/dts/apple/t6041.dtsi
+++ b/arch/arm64/boot/dts/apple/t6041.dtsi
@@ -314,6 +314,18 @@ l2_cache_2: l2-cache-2 {
 		};
 	};
 
+	pmu-e {
+		compatible = "apple,brava-e-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ 0 AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pmu-p {
+		compatible = "apple,brava-p-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ 0 AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	soc {
 		compatible = "simple-bus";
 		ranges;

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 12/13] arm64: dts: apple: t8132: Add PMU Device Nodes
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (10 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 11/13] arm64: dts: apple: t604x: " Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-03 10:14 ` [PATCH 13/13] arm64: dts: apple: t8140: " Myria Sarvay via B4 Relay
  2026-11-08 17:32 ` [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Joshua Peisach
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

Adds the PMU nodes to all t8132 devices.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 arch/arm64/boot/dts/apple/t8132.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8132.dtsi b/arch/arm64/boot/dts/apple/t8132.dtsi
index afec92a06015..d0f8a40097ee 100644
--- a/arch/arm64/boot/dts/apple/t8132.dtsi
+++ b/arch/arm64/boot/dts/apple/t8132.dtsi
@@ -189,6 +189,18 @@ clkref: clock-ref {
 		clock-output-names = "clkref";
 	};
 
+	pmu-e {
+		compatible = "apple,donan-e-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pmu-p {
+		compatible = "apple,donan-p-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	soc: soc {
 		compatible = "simple-bus";
 		#address-cells = <2>;

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 13/13] arm64: dts: apple: t8140: Add PMU Device Nodes
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (11 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 12/13] arm64: dts: apple: t8132: " Myria Sarvay via B4 Relay
@ 2026-11-03 10:14 ` Myria Sarvay via B4 Relay
  2026-11-08 17:32 ` [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Joshua Peisach
  13 siblings, 0 replies; 16+ messages in thread
From: Myria Sarvay via B4 Relay @ 2026-11-03 10:14 UTC (permalink / raw)
  To: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Myria Sarvay

From: Myria Sarvay <myrialsarvay@gmail.com>

Adds the PMU nodes to all t8140 devices.

Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
---
 arch/arm64/boot/dts/apple/t8140.dtsi | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/boot/dts/apple/t8140.dtsi b/arch/arm64/boot/dts/apple/t8140.dtsi
index 150d91bdf6fc..6e6fd5754406 100644
--- a/arch/arm64/boot/dts/apple/t8140.dtsi
+++ b/arch/arm64/boot/dts/apple/t8140.dtsi
@@ -136,6 +136,18 @@ l2_cache_1: l2-cache-1 {
 		};
 	};
 
+	pmu-e {
+		compatible = "apple,tahiti-e-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_E IRQ_TYPE_LEVEL_HIGH>;
+	};
+
+	pmu-p {
+		compatible = "apple,tahiti-p-pmu";
+		interrupt-parent = <&aic>;
+		interrupts = <AIC_FIQ AIC_CPU_PMU_P IRQ_TYPE_LEVEL_HIGH>;
+	};
+
 	soc: soc {
 		compatible = "simple-bus";
 		ranges;

-- 
2.56.0



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 01/13] dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles
  2026-11-03 10:14 ` [PATCH 01/13] dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles Myria Sarvay via B4 Relay
@ 2026-11-06 12:55   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 16+ messages in thread
From: Krzysztof Kozlowski @ 2026-11-06 12:55 UTC (permalink / raw)
  To: Myria Sarvay
  Cc: Will Deacon, Mark Rutland, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sven Peter, Janne Grunau, Neal Gompa, Marc Zyngier,
	linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen

On Tue, Nov 03, 2026 at 09:14:36PM +1100, Myria Sarvay wrote:
> Document the compatibles for all current M3, M4 and A18 Pro SoC PMU
> variants. Note that the M4+ are split out by chip codenames, instead of
> name for the types of cores, as they no longer have individual names for
> the performance and efficiency cores.
> 
> Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
> ---
>  Documentation/devicetree/bindings/arm/pmu.yaml | 8 ++++++++

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>

Best regards,
Krzysztof


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support
  2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
                   ` (12 preceding siblings ...)
  2026-11-03 10:14 ` [PATCH 13/13] arm64: dts: apple: t8140: " Myria Sarvay via B4 Relay
@ 2026-11-08 17:32 ` Joshua Peisach
  13 siblings, 0 replies; 16+ messages in thread
From: Joshua Peisach @ 2026-11-08 17:32 UTC (permalink / raw)
  To: myrialsarvay, Will Deacon, Mark Rutland, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sven Peter, Janne Grunau,
	Neal Gompa, Marc Zyngier
  Cc: linux-arm-kernel, linux-perf-users, devicetree, linux-kernel,
	asahi, Yuvan Shen, Nick Chan

On Tue Nov 3, 2026 at 5:14 AM EST, Myria Sarvay via B4 Relay wrote:
> This series adds support for the CPU PMU in the new M3, M4 and A18 SoCs
> presed in apple devices. These PMUs have new encodings for events, along
> with larger codes for these events. All of these events are as Apple
> describes them in the various kpep files found under /usr/share/kpep on
> macOS 27. More events may exist, but we have no idea of their affinity,
> or what they actually count, so we don't include them here.
>
> These patches have been tested on my own M2 (t8133-j413) and M3
> (t6031-j514c) devices, as well as by Yuvan on their M4 (t8132-j713)
> device.
>
> If possible, the device tree changes should probably go through
> apple-soc, as this is where the recently picked up M4 Pro/Max dts are.
>
> Tested-by: Yuvan Shen <yuvanshen09@gmail.com> # on t8132-j713
> Signed-off-by: Myria Sarvay <myrialsarvay@gmail.com>
> ---
> Myria Sarvay (12):
>       dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles
>       drivers/perf: apple_m1: Remove unused variables
>       drivers/perf: apple_m1: Support per-implementation event size
>       drivers/perf: apple_m1: Use macros for per-implementation init functions
>       drivers/perf: apple_m1: Add Apple M3 Series Support
>       drivers/perf: apple_m1: Add Apple M4 Series Support
>       drivers/perf: apple_m1: Add Apple A18 Support
>       arm64: dts: apple: t603x: Add PMU Device Nodes
>       arm64: dts: apple: t8122: Add PMU Device Nodes
>       arm64: dts: apple: t604x: Add PMU Device Nodes
>       arm64: dts: apple: t8132: Add PMU Device Nodes
>       arm64: dts: apple: t8140: Add PMU Device Nodes
>
Maybe the folder should be renamed to 'apple_arm' or something like
that?

> Nick Chan (1):
>       drivers/perf: apple_m1: Support per-implementation event tables
>
>  Documentation/devicetree/bindings/arm/pmu.yaml |   8 +
>  arch/arm64/boot/dts/apple/t6030.dtsi           |  12 +
>  arch/arm64/boot/dts/apple/t6031-base.dtsi      |  12 +
>  arch/arm64/boot/dts/apple/t6041.dtsi           |  12 +
>  arch/arm64/boot/dts/apple/t8122.dtsi           |  12 +
>  arch/arm64/boot/dts/apple/t8132.dtsi           |  12 +
>  arch/arm64/boot/dts/apple/t8140.dtsi           |  12 +
>  drivers/perf/apple_m1_cpu_pmu.c                | 664 ++++++++++++++++++++++---
>  8 files changed, 662 insertions(+), 82 deletions(-)
> ---
> base-commit: acb925da49876e74b806ccd48a7518d2d3368e5d
> change-id: 20260929-m3-plus-pmu-events-e4010ab44135
>
> Best regards,
> --  
> Myria Sarvay <myrialsarvay@gmail.com>


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2026-11-08 17:33 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-03 10:14 [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 01/13] dt-bindings: arm: pmu: Add Apple M3/M4/A18 Pro SoC CPU PMU compatibles Myria Sarvay via B4 Relay
2026-11-06 12:55   ` Krzysztof Kozlowski
2026-11-03 10:14 ` [PATCH 02/13] drivers/perf: apple_m1: Remove unused variables Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 03/13] drivers/perf: apple_m1: Support per-implementation event tables Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 04/13] drivers/perf: apple_m1: Support per-implementation event size Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 05/13] drivers/perf: apple_m1: Use macros for per-implementation init functions Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 06/13] drivers/perf: apple_m1: Add Apple M3 Series Support Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 07/13] drivers/perf: apple_m1: Add Apple M4 " Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 08/13] drivers/perf: apple_m1: Add Apple A18 Support Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 09/13] arm64: dts: apple: t603x: Add PMU Device Nodes Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 10/13] arm64: dts: apple: t8122: " Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 11/13] arm64: dts: apple: t604x: " Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 12/13] arm64: dts: apple: t8132: " Myria Sarvay via B4 Relay
2026-11-03 10:14 ` [PATCH 13/13] arm64: dts: apple: t8140: " Myria Sarvay via B4 Relay
2026-11-08 17:32 ` [PATCH 00/13] drivers/perf: apple_m1: Add M3/M4/A18 Pro Support Joshua Peisach

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®