Skip to content

Commit eae8983

Browse files
ouptonjannau
authored andcommitted
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> Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Reviewed-by: Marc Zyngier <maz@kernel.org>
1 parent 037dde4 commit eae8983

1 file changed

Lines changed: 32 additions & 20 deletions

File tree

drivers/perf/apple_m1_cpu_pmu.c

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

328-
static void m1_pmu_configure_counter(unsigned int index, u8 event,
329-
bool user, bool kernel)
328+
static void __m1_pmu_configure_event_filter(unsigned int index, bool user,
329+
bool kernel)
330330
{
331-
u64 val, user_bit, kernel_bit;
332-
int shift;
331+
u64 clear, set, user_bit, kernel_bit;
333332

334333
switch (index) {
335334
case 0 ... 7:
@@ -344,19 +343,24 @@ static void m1_pmu_configure_counter(unsigned int index, u8 event,
344343
BUG();
345344
}
346345

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

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

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

361365
/*
362366
* Counters 0 and 1 have fixed events. For anything else,
@@ -369,21 +373,29 @@ static void m1_pmu_configure_counter(unsigned int index, u8 event,
369373
break;
370374
case 2 ... 5:
371375
shift = (index - 2) * 8;
372-
val = read_sysreg_s(SYS_IMP_APL_PMESR0_EL1);
373-
val &= ~((u64)0xff << shift);
374-
val |= (u64)event << shift;
375-
write_sysreg_s(val, SYS_IMP_APL_PMESR0_EL1);
376+
clear |= (u64)0xff << shift;
377+
set |= (u64)event << shift;
378+
sysreg_clear_set_s(SYS_IMP_APL_PMESR0_EL1, clear, set);
376379
break;
377380
case 6 ... 9:
378381
shift = (index - 6) * 8;
379-
val = read_sysreg_s(SYS_IMP_APL_PMESR1_EL1);
380-
val &= ~((u64)0xff << shift);
381-
val |= (u64)event << shift;
382-
write_sysreg_s(val, SYS_IMP_APL_PMESR1_EL1);
382+
clear |= (u64)0xff << shift;
383+
set |= (u64)event << shift;
384+
sysreg_clear_set_s(SYS_IMP_APL_PMESR1_EL1, clear, set);
383385
break;
384386
}
385387
}
386388

389+
static void m1_pmu_configure_counter(unsigned int index, unsigned long config_base)
390+
{
391+
bool kernel = config_base & M1_PMU_CFG_COUNT_KERNEL;
392+
bool user = config_base & M1_PMU_CFG_COUNT_USER;
393+
u8 evt = config_base & M1_PMU_CFG_EVENT;
394+
395+
__m1_pmu_configure_event_filter(index, user, kernel);
396+
__m1_pmu_configure_eventsel(index, evt);
397+
}
398+
387399
/* arm_pmu backend */
388400
static void m1_pmu_enable_event(struct perf_event *event)
389401
{
@@ -398,7 +410,7 @@ static void m1_pmu_enable_event(struct perf_event *event)
398410
m1_pmu_disable_counter(event->hw.idx);
399411
isb();
400412

401-
m1_pmu_configure_counter(event->hw.idx, evt, user, kernel);
413+
m1_pmu_configure_counter(event->hw.idx, event->hw.config_base);
402414
m1_pmu_enable_counter(event->hw.idx);
403415
m1_pmu_enable_counter_interrupt(event->hw.idx);
404416
isb();

0 commit comments

Comments
 (0)