aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlbin Tonnerre <albin.tonnerre@arm.com>2014-01-29 09:28:57 -0500
committerWill Deacon <will.deacon@arm.com>2014-02-21 06:11:23 -0500
commit8e781f65423c2e8e65a56972ba996b6c01a5ef3e (patch)
tree043d0048fbd9125087dce47a52956211c296c603
parent51e5fef62059e4074054ee731385e0dc7ca561ff (diff)
ARM: perf: add support for the Cortex-A12 PMU
Cortex-A12 implements Performance Monitors compliant with the PMUv2 architecture. This patch adds support for the Cortex-A12 PMU to the ARM perf backend. Signed-off-by: Albin Tonnerre <albin.tonnerre@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--Documentation/devicetree/bindings/arm/pmu.txt1
-rw-r--r--arch/arm/kernel/perf_event_cpu.c1
-rw-r--r--arch/arm/kernel/perf_event_v7.c158
3 files changed, 160 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt
index ce731441e64f..fe5cef8976cb 100644
--- a/Documentation/devicetree/bindings/arm/pmu.txt
+++ b/Documentation/devicetree/bindings/arm/pmu.txt
@@ -9,6 +9,7 @@ Required properties:
9- compatible : should be one of 9- compatible : should be one of
10 "arm,armv8-pmuv3" 10 "arm,armv8-pmuv3"
11 "arm,cortex-a15-pmu" 11 "arm,cortex-a15-pmu"
12 "arm,cortex-a12-pmu"
12 "arm,cortex-a9-pmu" 13 "arm,cortex-a9-pmu"
13 "arm,cortex-a8-pmu" 14 "arm,cortex-a8-pmu"
14 "arm,cortex-a7-pmu" 15 "arm,cortex-a7-pmu"
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
index 326cb58de2f8..51798d7854ac 100644
--- a/arch/arm/kernel/perf_event_cpu.c
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -222,6 +222,7 @@ static struct notifier_block cpu_pmu_hotplug_notifier = {
222 */ 222 */
223static struct of_device_id cpu_pmu_of_device_ids[] = { 223static struct of_device_id cpu_pmu_of_device_ids[] = {
224 {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init}, 224 {.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init},
225 {.compatible = "arm,cortex-a12-pmu", .data = armv7_a12_pmu_init},
225 {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init}, 226 {.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init},
226 {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init}, 227 {.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init},
227 {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init}, 228 {.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init},
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 2fce4751f4c0..f4ef3981ed02 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -113,6 +113,19 @@ enum armv7_a15_perf_types {
113 ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76, 113 ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
114}; 114};
115 115
116/* ARMv7 Cortex-A12 specific event types */
117enum armv7_a12_perf_types {
118 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
119 ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
120
121 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
122 ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
123
124 ARMV7_A12_PERFCTR_PC_WRITE_SPEC = 0x76,
125
126 ARMV7_A12_PERFCTR_PF_TLB_REFILL = 0xe7,
127};
128
116/* ARMv7 Krait specific event types */ 129/* ARMv7 Krait specific event types */
117enum krait_perf_types { 130enum krait_perf_types {
118 KRAIT_PMRESR0_GROUP0 = 0xcc, 131 KRAIT_PMRESR0_GROUP0 = 0xcc,
@@ -750,6 +763,130 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
750}; 763};
751 764
752/* 765/*
766 * Cortex-A12 HW events mapping
767 */
768static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
769 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
770 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
771 [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
772 [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
773 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
774 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
775 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
776 [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
777 [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
778};
779
780static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
781 [PERF_COUNT_HW_CACHE_OP_MAX]
782 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
783 [C(L1D)] = {
784 [C(OP_READ)] = {
785 [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
786 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
787 },
788 [C(OP_WRITE)] = {
789 [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
790 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
791 },
792 [C(OP_PREFETCH)] = {
793 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
794 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
795 },
796 },
797 [C(L1I)] = {
798 /*
799 * Not all performance counters differentiate between read
800 * and write accesses/misses so we're not always strictly
801 * correct, but it's the best we can do. Writes and reads get
802 * combined in these cases.
803 */
804 [C(OP_READ)] = {
805 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
806 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
807 },
808 [C(OP_WRITE)] = {
809 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
810 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
811 },
812 [C(OP_PREFETCH)] = {
813 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
814 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
815 },
816 },
817 [C(LL)] = {
818 [C(OP_READ)] = {
819 [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
820 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
821 },
822 [C(OP_WRITE)] = {
823 [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
824 [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
825 },
826 [C(OP_PREFETCH)] = {
827 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
828 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
829 },
830 },
831 [C(DTLB)] = {
832 [C(OP_READ)] = {
833 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
834 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
835 },
836 [C(OP_WRITE)] = {
837 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
838 [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
839 },
840 [C(OP_PREFETCH)] = {
841 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
842 [C(RESULT_MISS)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
843 },
844 },
845 [C(ITLB)] = {
846 [C(OP_READ)] = {
847 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
848 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
849 },
850 [C(OP_WRITE)] = {
851 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
852 [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
853 },
854 [C(OP_PREFETCH)] = {
855 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
856 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
857 },
858 },
859 [C(BPU)] = {
860 [C(OP_READ)] = {
861 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
862 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
863 },
864 [C(OP_WRITE)] = {
865 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
866 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
867 },
868 [C(OP_PREFETCH)] = {
869 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
870 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
871 },
872 },
873 [C(NODE)] = {
874 [C(OP_READ)] = {
875 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
876 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
877 },
878 [C(OP_WRITE)] = {
879 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
880 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
881 },
882 [C(OP_PREFETCH)] = {
883 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
884 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
885 },
886 },
887};
888
889/*
753 * Krait HW events mapping 890 * Krait HW events mapping
754 */ 891 */
755static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = { 892static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
@@ -1362,6 +1499,12 @@ static int armv7_a7_map_event(struct perf_event *event)
1362 &armv7_a7_perf_cache_map, 0xFF); 1499 &armv7_a7_perf_cache_map, 0xFF);
1363} 1500}
1364 1501
1502static int armv7_a12_map_event(struct perf_event *event)
1503{
1504 return armpmu_map_event(event, &armv7_a12_perf_map,
1505 &armv7_a12_perf_cache_map, 0xFF);
1506}
1507
1365static int krait_map_event(struct perf_event *event) 1508static int krait_map_event(struct perf_event *event)
1366{ 1509{
1367 return armpmu_map_event(event, &krait_perf_map, 1510 return armpmu_map_event(event, &krait_perf_map,
@@ -1446,6 +1589,16 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1446 return 0; 1589 return 0;
1447} 1590}
1448 1591
1592static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
1593{
1594 armv7pmu_init(cpu_pmu);
1595 cpu_pmu->name = "ARMv7 Cortex-A12";
1596 cpu_pmu->map_event = armv7_a12_map_event;
1597 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1598 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1599 return 0;
1600}
1601
1449/* 1602/*
1450 * Krait Performance Monitor Region Event Selection Register (PMRESRn) 1603 * Krait Performance Monitor Region Event Selection Register (PMRESRn)
1451 * 1604 *
@@ -1863,6 +2016,11 @@ static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1863 return -ENODEV; 2016 return -ENODEV;
1864} 2017}
1865 2018
2019static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
2020{
2021 return -ENODEV;
2022}
2023
1866static inline int krait_pmu_init(struct arm_pmu *cpu_pmu) 2024static inline int krait_pmu_init(struct arm_pmu *cpu_pmu)
1867{ 2025{
1868 return -ENODEV; 2026 return -ENODEV;