Skip to content

Commit 75ecffc

Browse files
committed
drivers/perf: apple_m1: Refactor event select/filter configuration
Supporting guest mode events will necessitate programming two event filters. Prepare by splitting up the programming of the event selector + event filter into separate headers. Opportunistically replace RMW patterns with sysreg_clear_set_s(). Tested-by: Janne Grunau <j@jannau.net> Reviewed-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20250305202641.428114-2-oliver.upton@linux.dev Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
1 parent 0ad2507 commit 75ecffc

File tree

1 file changed

+32
-20
lines changed

1 file changed

+32
-20
lines changed

drivers/perf/apple_m1_cpu_pmu.c

Lines changed: 32 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -327,11 +327,10 @@ static void m1_pmu_disable_counter_interrupt(unsigned int index)
327327
__m1_pmu_enable_counter_interrupt(index, false);
328328
}
329329

330-
static void m1_pmu_configure_counter(unsigned int index, u8 event,
331-
bool user, bool kernel)
330+
static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
331+
bool kernel)
332332
{
333-
u64 val, user_bit, kernel_bit;
334-
int shift;
333+
u64 clear, set, user_bit, kernel_bit;
335334

336335
switch (index) {
337336
case 0 ... 7:
@@ -346,19 +345,24 @@ static void m1_pmu_configure_counter(unsigned int index, u8 event,
346345
BUG();
347346
}
348347

349-
val = read_sysreg_s(SYS_IMP_APL_PMCR1_EL1);
350-
348+
clear = set = 0;
351349
if (user)
352-
val |= user_bit;
350+
set |= user_bit;
353351
else
354-
val &= ~user_bit;
352+
clear |= user_bit;
355353

356354
if (kernel)
357-
val |= kernel_bit;
355+
set |= kernel_bit;
358356
else
359-
val &= ~kernel_bit;
357+
clear |= kernel_bit;
360358

361-
write_sysreg_s(val, SYS_IMP_APL_PMCR1_EL1);
359+
sysreg_clear_set_s(SYS_IMP_APL_PMCR1_EL1, clear, set);
360+
}
361+
362+
static void __m1_pmu_configure_eventsel(unsigned int index, u8 event)
363+
{
364+
u64 clear = 0, set = 0;
365+
int shift;
362366

363367
/*
364368
* Counters 0 and 1 have fixed events. For anything else,
@@ -371,21 +375,29 @@ static void m1_pmu_configure_counter(unsigned int index, u8 event,
371375
break;
372376
case 2 ... 5:
373377
shift = (index - 2) * 8;
374-
val = read_sysreg_s(SYS_IMP_APL_PMESR0_EL1);
375-
val &= ~((u64)0xff << shift);
376-
val |= (u64)event << shift;
377-
write_sysreg_s(val, SYS_IMP_APL_PMESR0_EL1);
378+
clear |= (u64)0xff << shift;
379+
set |= (u64)event << shift;
380+
sysreg_clear_set_s(SYS_IMP_APL_PMESR0_EL1, clear, set);
378381
break;
379382
case 6 ... 9:
380383
shift = (index - 6) * 8;
381-
val = read_sysreg_s(SYS_IMP_APL_PMESR1_EL1);
382-
val &= ~((u64)0xff << shift);
383-
val |= (u64)event << shift;
384-
write_sysreg_s(val, SYS_IMP_APL_PMESR1_EL1);
384+
clear |= (u64)0xff << shift;
385+
set |= (u64)event << shift;
386+
sysreg_clear_set_s(SYS_IMP_APL_PMESR1_EL1, clear, set);
385387
break;
386388
}
387389
}
388390

391+
static void m1_pmu_configure_counter(unsigned int index, unsigned long config_base)
392+
{
393+
bool kernel = config_base & M1_PMU_CFG_COUNT_KERNEL;
394+
bool user = config_base & M1_PMU_CFG_COUNT_USER;
395+
u8 evt = config_base & M1_PMU_CFG_EVENT;
396+
397+
__m1_pmu_configure_event_filter(index, user, kernel);
398+
__m1_pmu_configure_eventsel(index, evt);
399+
}
400+
389401
/* arm_pmu backend */
390402
static void m1_pmu_enable_event(struct perf_event *event)
391403
{
@@ -400,7 +412,7 @@ static void m1_pmu_enable_event(struct perf_event *event)
400412
m1_pmu_disable_counter(event->hw.idx);
401413
isb();
402414

403-
m1_pmu_configure_counter(event->hw.idx, evt, user, kernel);
415+
m1_pmu_configure_counter(event->hw.idx, event->hw.config_base);
404416
m1_pmu_enable_counter(event->hw.idx);
405417
m1_pmu_enable_counter_interrupt(event->hw.idx);
406418
isb();

0 commit comments

Comments
 (0)