@@ -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 */
388400static 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