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