kernel_samsung_a53x/drivers/soc/samsung/xperf/pmufunc.h
2024-06-15 16:02:09 -03:00

184 lines
4 KiB
C
Executable file

/*
* PMU Counter API
* Author: Jungwook Kim, jwook1.kim@samsung.com
*
*/
typedef unsigned long ccnt_t;
#ifdef _PMU_COUNT_64
static inline void pmu_enable_counter(u64 val)
{
val = 1L << val;
asm volatile("msr PMCNTENSET_EL0, %0" : : "r" (val));
}
static inline void pmu_disable_counter(u64 val)
{
val = 1L << val;
asm volatile("msr PMCNTENCLR_EL0, %0" : : "r" (val));
}
static inline void pmnc_config(u64 counter, u64 event)
{
counter = counter & 0x1F;
asm volatile("msr PMSELR_EL0, %0" : : "r" (counter));
asm volatile("msr PMXEVTYPER_EL0, %0" : : "r" (event));
}
static inline void pmnc_reset(void)
{
u64 val;
asm volatile("mrs %0, PMCR_EL0" : "=r"(val));
val = val | 0x2;
asm volatile("msr PMCR_EL0, %0" : : "r"(val));
}
static inline ccnt_t pmnc_read2(u64 counter)
{
ccnt_t ret;
counter = counter & 0x1F;
asm volatile("msr PMSELR_EL0, %0" : : "r" (counter));
asm volatile("mrs %0, PMXEVCNTR_EL0" : "=r"(ret));
return ret;
}
static inline void enable_pmu(void)
{
u64 val;
asm volatile("mrs %0, PMCR_EL0" : "=r"(val));
val = val | 0x1; // set E bit
asm volatile("msr PMCR_EL0, %0" : : "r"(val));
}
static inline void disable_pmu(void)
{
u64 val;
asm volatile("mrs %0, PMCR_EL0" : "=r"(val));
val = val & ~0x1; // clear E bit
asm volatile("msr PMCR_EL0, %0" : : "r"(val));
}
static inline u32 read_pmnc(void)
{
u64 val;
asm volatile("mrs %0, PMCR_EL0" : "=r"(val));
return val;
}
static inline void disable_ccnt(void)
{
u64 val = 0x80000000;
asm volatile("msr PMCNTENCLR_EL0, %0" : : "r" (val));
}
static inline void enable_ccnt(void)
{
u64 val = 0x80000000;
asm volatile("msr PMCNTENSET_EL0, %0" : : "r" (val));
}
static inline void reset_ccnt(void)
{
u64 val;
asm volatile("mrs %0, PMCR_EL0" : "=r"(val));
val = val | 0x4; // set C bit
asm volatile("msr PMCR_EL0, %0" : : "r"(val));
}
static inline ccnt_t read_ccnt(void)
{
ccnt_t val;
asm volatile("mrs %0, PMCCNTR_EL0" : "=r"(val));
return val;
}
#else
static inline void pmu_enable_counter(u32 val)
{
val = 1 << val;
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (val));
}
static inline void pmu_disable_counter(u32 val)
{
val = 1 << val;
asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (val));
}
static inline void pmnc_config(u32 counter, u32 event)
{
counter = counter & 0x1F;
asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r"(counter));
asm volatile("mcr p15, 0, %0, c9, c13, 1" : : "r"(event));
}
static inline void pmnc_reset(void)
{
u32 val;
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
val = val | 0x2;
asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
}
static inline ccnt_t pmnc_read2(u32 counter)
{
ccnt_t ret;
counter = counter & 0x1F;
asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r"(counter));
asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r"(ret));
return ret;
}
static inline void enable_pmu(void)
{
u32 val;
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
val = val | 0x1; // set E bit
asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
}
static inline void disable_pmu(void)
{
u32 val;
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
val = val & ~0x1; // clear E bit
asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
}
static inline u32 read_pmnc(void)
{
u32 val;
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
return val;
}
static inline void disable_ccnt(void)
{
u32 val = 0x80000000;
asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r"(val));
}
static inline void enable_ccnt(void)
{
u32 val = 0x80000000;
asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r"(val));
}
static inline void reset_ccnt(void)
{
u32 val;
asm volatile("mrc p15, 0, %0, c9, c12, 0" : "=r"(val));
val = val | 0x4; // set C bit
asm volatile("mcr p15, 0, %0, c9, c12, 0" : : "r"(val));
}
static inline ccnt_t read_ccnt(void)
{
ccnt_t val;
asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r"(val));
return val;
}
#endif
#define __start_timer(x) (enable_pmu(), disable_ccnt(), reset_ccnt(), enable_ccnt())
#define __stop_timer(x) read_ccnt()