184 lines
4 KiB
C
Executable file
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()
|