17520fa99SSuzuki K Poulose /*
27520fa99SSuzuki K Poulose  * ARM DynamIQ Shared Unit (DSU) PMU Low level register access routines.
37520fa99SSuzuki K Poulose  *
47520fa99SSuzuki K Poulose  * Copyright (C) ARM Limited, 2017.
57520fa99SSuzuki K Poulose  *
67520fa99SSuzuki K Poulose  * Author: Suzuki K Poulose <suzuki.poulose@arm.com>
77520fa99SSuzuki K Poulose  *
87520fa99SSuzuki K Poulose  * This program is free software; you can redistribute it and/or
97520fa99SSuzuki K Poulose  * modify it under the terms of the GNU General Public License
107520fa99SSuzuki K Poulose  * version 2, as published by the Free Software Foundation.
117520fa99SSuzuki K Poulose  */
127520fa99SSuzuki K Poulose 
137520fa99SSuzuki K Poulose #include <linux/bitops.h>
147520fa99SSuzuki K Poulose #include <linux/build_bug.h>
157520fa99SSuzuki K Poulose #include <linux/compiler.h>
167520fa99SSuzuki K Poulose #include <linux/types.h>
177520fa99SSuzuki K Poulose #include <asm/barrier.h>
187520fa99SSuzuki K Poulose #include <asm/sysreg.h>
197520fa99SSuzuki K Poulose 
207520fa99SSuzuki K Poulose 
217520fa99SSuzuki K Poulose #define CLUSTERPMCR_EL1			sys_reg(3, 0, 15, 5, 0)
227520fa99SSuzuki K Poulose #define CLUSTERPMCNTENSET_EL1		sys_reg(3, 0, 15, 5, 1)
237520fa99SSuzuki K Poulose #define CLUSTERPMCNTENCLR_EL1		sys_reg(3, 0, 15, 5, 2)
247520fa99SSuzuki K Poulose #define CLUSTERPMOVSSET_EL1		sys_reg(3, 0, 15, 5, 3)
257520fa99SSuzuki K Poulose #define CLUSTERPMOVSCLR_EL1		sys_reg(3, 0, 15, 5, 4)
267520fa99SSuzuki K Poulose #define CLUSTERPMSELR_EL1		sys_reg(3, 0, 15, 5, 5)
277520fa99SSuzuki K Poulose #define CLUSTERPMINTENSET_EL1		sys_reg(3, 0, 15, 5, 6)
287520fa99SSuzuki K Poulose #define CLUSTERPMINTENCLR_EL1		sys_reg(3, 0, 15, 5, 7)
297520fa99SSuzuki K Poulose #define CLUSTERPMCCNTR_EL1		sys_reg(3, 0, 15, 6, 0)
307520fa99SSuzuki K Poulose #define CLUSTERPMXEVTYPER_EL1		sys_reg(3, 0, 15, 6, 1)
317520fa99SSuzuki K Poulose #define CLUSTERPMXEVCNTR_EL1		sys_reg(3, 0, 15, 6, 2)
327520fa99SSuzuki K Poulose #define CLUSTERPMMDCR_EL1		sys_reg(3, 0, 15, 6, 3)
337520fa99SSuzuki K Poulose #define CLUSTERPMCEID0_EL1		sys_reg(3, 0, 15, 6, 4)
347520fa99SSuzuki K Poulose #define CLUSTERPMCEID1_EL1		sys_reg(3, 0, 15, 6, 5)
357520fa99SSuzuki K Poulose 
367520fa99SSuzuki K Poulose static inline u32 __dsu_pmu_read_pmcr(void)
377520fa99SSuzuki K Poulose {
387520fa99SSuzuki K Poulose 	return read_sysreg_s(CLUSTERPMCR_EL1);
397520fa99SSuzuki K Poulose }
407520fa99SSuzuki K Poulose 
417520fa99SSuzuki K Poulose static inline void __dsu_pmu_write_pmcr(u32 val)
427520fa99SSuzuki K Poulose {
437520fa99SSuzuki K Poulose 	write_sysreg_s(val, CLUSTERPMCR_EL1);
447520fa99SSuzuki K Poulose 	isb();
457520fa99SSuzuki K Poulose }
467520fa99SSuzuki K Poulose 
477520fa99SSuzuki K Poulose static inline u32 __dsu_pmu_get_reset_overflow(void)
487520fa99SSuzuki K Poulose {
497520fa99SSuzuki K Poulose 	u32 val = read_sysreg_s(CLUSTERPMOVSCLR_EL1);
507520fa99SSuzuki K Poulose 	/* Clear the bit */
517520fa99SSuzuki K Poulose 	write_sysreg_s(val, CLUSTERPMOVSCLR_EL1);
527520fa99SSuzuki K Poulose 	isb();
537520fa99SSuzuki K Poulose 	return val;
547520fa99SSuzuki K Poulose }
557520fa99SSuzuki K Poulose 
567520fa99SSuzuki K Poulose static inline void __dsu_pmu_select_counter(int counter)
577520fa99SSuzuki K Poulose {
587520fa99SSuzuki K Poulose 	write_sysreg_s(counter, CLUSTERPMSELR_EL1);
597520fa99SSuzuki K Poulose 	isb();
607520fa99SSuzuki K Poulose }
617520fa99SSuzuki K Poulose 
627520fa99SSuzuki K Poulose static inline u64 __dsu_pmu_read_counter(int counter)
637520fa99SSuzuki K Poulose {
647520fa99SSuzuki K Poulose 	__dsu_pmu_select_counter(counter);
657520fa99SSuzuki K Poulose 	return read_sysreg_s(CLUSTERPMXEVCNTR_EL1);
667520fa99SSuzuki K Poulose }
677520fa99SSuzuki K Poulose 
687520fa99SSuzuki K Poulose static inline void __dsu_pmu_write_counter(int counter, u64 val)
697520fa99SSuzuki K Poulose {
707520fa99SSuzuki K Poulose 	__dsu_pmu_select_counter(counter);
717520fa99SSuzuki K Poulose 	write_sysreg_s(val, CLUSTERPMXEVCNTR_EL1);
727520fa99SSuzuki K Poulose 	isb();
737520fa99SSuzuki K Poulose }
747520fa99SSuzuki K Poulose 
757520fa99SSuzuki K Poulose static inline void __dsu_pmu_set_event(int counter, u32 event)
767520fa99SSuzuki K Poulose {
777520fa99SSuzuki K Poulose 	__dsu_pmu_select_counter(counter);
787520fa99SSuzuki K Poulose 	write_sysreg_s(event, CLUSTERPMXEVTYPER_EL1);
797520fa99SSuzuki K Poulose 	isb();
807520fa99SSuzuki K Poulose }
817520fa99SSuzuki K Poulose 
827520fa99SSuzuki K Poulose static inline u64 __dsu_pmu_read_pmccntr(void)
837520fa99SSuzuki K Poulose {
847520fa99SSuzuki K Poulose 	return read_sysreg_s(CLUSTERPMCCNTR_EL1);
857520fa99SSuzuki K Poulose }
867520fa99SSuzuki K Poulose 
877520fa99SSuzuki K Poulose static inline void __dsu_pmu_write_pmccntr(u64 val)
887520fa99SSuzuki K Poulose {
897520fa99SSuzuki K Poulose 	write_sysreg_s(val, CLUSTERPMCCNTR_EL1);
907520fa99SSuzuki K Poulose 	isb();
917520fa99SSuzuki K Poulose }
927520fa99SSuzuki K Poulose 
937520fa99SSuzuki K Poulose static inline void __dsu_pmu_disable_counter(int counter)
947520fa99SSuzuki K Poulose {
957520fa99SSuzuki K Poulose 	write_sysreg_s(BIT(counter), CLUSTERPMCNTENCLR_EL1);
967520fa99SSuzuki K Poulose 	isb();
977520fa99SSuzuki K Poulose }
987520fa99SSuzuki K Poulose 
997520fa99SSuzuki K Poulose static inline void __dsu_pmu_enable_counter(int counter)
1007520fa99SSuzuki K Poulose {
1017520fa99SSuzuki K Poulose 	write_sysreg_s(BIT(counter), CLUSTERPMCNTENSET_EL1);
1027520fa99SSuzuki K Poulose 	isb();
1037520fa99SSuzuki K Poulose }
1047520fa99SSuzuki K Poulose 
1057520fa99SSuzuki K Poulose static inline void __dsu_pmu_counter_interrupt_enable(int counter)
1067520fa99SSuzuki K Poulose {
1077520fa99SSuzuki K Poulose 	write_sysreg_s(BIT(counter), CLUSTERPMINTENSET_EL1);
1087520fa99SSuzuki K Poulose 	isb();
1097520fa99SSuzuki K Poulose }
1107520fa99SSuzuki K Poulose 
1117520fa99SSuzuki K Poulose static inline void __dsu_pmu_counter_interrupt_disable(int counter)
1127520fa99SSuzuki K Poulose {
1137520fa99SSuzuki K Poulose 	write_sysreg_s(BIT(counter), CLUSTERPMINTENCLR_EL1);
1147520fa99SSuzuki K Poulose 	isb();
1157520fa99SSuzuki K Poulose }
1167520fa99SSuzuki K Poulose 
1177520fa99SSuzuki K Poulose 
1187520fa99SSuzuki K Poulose static inline u32 __dsu_pmu_read_pmceid(int n)
1197520fa99SSuzuki K Poulose {
1207520fa99SSuzuki K Poulose 	switch (n) {
1217520fa99SSuzuki K Poulose 	case 0:
1227520fa99SSuzuki K Poulose 		return read_sysreg_s(CLUSTERPMCEID0_EL1);
1237520fa99SSuzuki K Poulose 	case 1:
1247520fa99SSuzuki K Poulose 		return read_sysreg_s(CLUSTERPMCEID1_EL1);
1257520fa99SSuzuki K Poulose 	default:
1267520fa99SSuzuki K Poulose 		BUILD_BUG();
1277520fa99SSuzuki K Poulose 		return 0;
1287520fa99SSuzuki K Poulose 	}
1297520fa99SSuzuki K Poulose }
130