diff options
author | Albin Tonnerre <albin.tonnerre@arm.com> | 2014-01-29 09:28:57 -0500 |
---|---|---|
committer | Will Deacon <will.deacon@arm.com> | 2014-02-21 06:11:23 -0500 |
commit | 8e781f65423c2e8e65a56972ba996b6c01a5ef3e (patch) | |
tree | 043d0048fbd9125087dce47a52956211c296c603 | |
parent | 51e5fef62059e4074054ee731385e0dc7ca561ff (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.txt | 1 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event_cpu.c | 1 | ||||
-rw-r--r-- | arch/arm/kernel/perf_event_v7.c | 158 |
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 | */ |
223 | static struct of_device_id cpu_pmu_of_device_ids[] = { | 223 | static 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 */ | ||
117 | enum 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 */ |
117 | enum krait_perf_types { | 130 | enum 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 | */ | ||
768 | static 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 | |||
780 | static 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 | */ |
755 | static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = { | 892 | static 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 | ||
1502 | static 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 | |||
1365 | static int krait_map_event(struct perf_event *event) | 1508 | static 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 | ||
1592 | static 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 | ||
2019 | static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu) | ||
2020 | { | ||
2021 | return -ENODEV; | ||
2022 | } | ||
2023 | |||
1866 | static inline int krait_pmu_init(struct arm_pmu *cpu_pmu) | 2024 | static inline int krait_pmu_init(struct arm_pmu *cpu_pmu) |
1867 | { | 2025 | { |
1868 | return -ENODEV; | 2026 | return -ENODEV; |