aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2014-02-07 16:01:21 -0500
committerWill Deacon <will.deacon@arm.com>2014-02-21 06:11:02 -0500
commit2a3391cdb3c7bbea3be5cb39279764843a15ef25 (patch)
treee95bd4ba504b0c2bda02386e84d49f2f1fc1b699
parent3a3967ed9135f931f3848b0c946dcf3c10ca9f9a (diff)
ARM: perf: add basic support for Krait CPU PMUs
Add basic support for the Krait CPU PMU. This allows us to use the architected functionality of the PMU. This is based on code originally written by Ashwin Chaugule and Neil Leeder [1]. [1] https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/arch/arm/kernel/perf_event_msm_krait.c?h=msm-3.4 Cc: Neil Leeder <nleeder@codeaurora.org> Cc: Ashwin Chaugule <ashwinc@codeaurora.org> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm/kernel/perf_event_cpu.c1
-rw-r--r--arch/arm/kernel/perf_event_v7.c164
2 files changed, 165 insertions, 0 deletions
diff --git a/arch/arm/kernel/perf_event_cpu.c b/arch/arm/kernel/perf_event_cpu.c
index 68d02ca0ca1b..ed571d386c0b 100644
--- a/arch/arm/kernel/perf_event_cpu.c
+++ b/arch/arm/kernel/perf_event_cpu.c
@@ -229,6 +229,7 @@ static struct of_device_id cpu_pmu_of_device_ids[] = {
229 {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init}, 229 {.compatible = "arm,arm11mpcore-pmu", .data = armv6mpcore_pmu_init},
230 {.compatible = "arm,arm1176-pmu", .data = armv6pmu_init}, 230 {.compatible = "arm,arm1176-pmu", .data = armv6pmu_init},
231 {.compatible = "arm,arm1136-pmu", .data = armv6pmu_init}, 231 {.compatible = "arm,arm1136-pmu", .data = armv6pmu_init},
232 {.compatible = "qcom,krait-pmu", .data = krait_pmu_init},
232 {}, 233 {},
233}; 234};
234 235
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 039cffb053a7..16386b1d27a8 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -732,6 +732,138 @@ static const unsigned armv7_a7_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
732}; 732};
733 733
734/* 734/*
735 * Krait HW events mapping
736 */
737static const unsigned krait_perf_map[PERF_COUNT_HW_MAX] = {
738 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
739 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
740 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
741 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
742 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
743 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
744 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
745};
746
747static const unsigned krait_perf_map_no_branch[PERF_COUNT_HW_MAX] = {
748 [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
749 [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
750 [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
751 [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
752 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = HW_OP_UNSUPPORTED,
753 [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
754 [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_CLOCK_CYCLES,
755};
756
757static const unsigned krait_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
758 [PERF_COUNT_HW_CACHE_OP_MAX]
759 [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
760 [C(L1D)] = {
761 /*
762 * The performance counters don't differentiate between read
763 * and write accesses/misses so this isn't strictly correct,
764 * but it's the best we can do. Writes and reads get
765 * combined.
766 */
767 [C(OP_READ)] = {
768 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
769 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
770 },
771 [C(OP_WRITE)] = {
772 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
773 [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
774 },
775 [C(OP_PREFETCH)] = {
776 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
777 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
778 },
779 },
780 [C(L1I)] = {
781 [C(OP_READ)] = {
782 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
783 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
784 },
785 [C(OP_WRITE)] = {
786 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
787 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
788 },
789 [C(OP_PREFETCH)] = {
790 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
791 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
792 },
793 },
794 [C(LL)] = {
795 [C(OP_READ)] = {
796 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
797 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
798 },
799 [C(OP_WRITE)] = {
800 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
801 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
802 },
803 [C(OP_PREFETCH)] = {
804 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
805 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
806 },
807 },
808 [C(DTLB)] = {
809 [C(OP_READ)] = {
810 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
811 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
812 },
813 [C(OP_WRITE)] = {
814 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
815 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
816 },
817 [C(OP_PREFETCH)] = {
818 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
819 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
820 },
821 },
822 [C(ITLB)] = {
823 [C(OP_READ)] = {
824 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
825 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
826 },
827 [C(OP_WRITE)] = {
828 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
829 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
830 },
831 [C(OP_PREFETCH)] = {
832 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
833 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
834 },
835 },
836 [C(BPU)] = {
837 [C(OP_READ)] = {
838 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
839 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
840 },
841 [C(OP_WRITE)] = {
842 [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
843 [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
844 },
845 [C(OP_PREFETCH)] = {
846 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
847 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
848 },
849 },
850 [C(NODE)] = {
851 [C(OP_READ)] = {
852 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
853 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
854 },
855 [C(OP_WRITE)] = {
856 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
857 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
858 },
859 [C(OP_PREFETCH)] = {
860 [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
861 [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
862 },
863 },
864};
865
866/*
735 * Perf Events' indices 867 * Perf Events' indices
736 */ 868 */
737#define ARMV7_IDX_CYCLE_COUNTER 0 869#define ARMV7_IDX_CYCLE_COUNTER 0
@@ -1212,6 +1344,18 @@ static int armv7_a7_map_event(struct perf_event *event)
1212 &armv7_a7_perf_cache_map, 0xFF); 1344 &armv7_a7_perf_cache_map, 0xFF);
1213} 1345}
1214 1346
1347static int krait_map_event(struct perf_event *event)
1348{
1349 return armpmu_map_event(event, &krait_perf_map,
1350 &krait_perf_cache_map, 0xFFFFF);
1351}
1352
1353static int krait_map_event_no_branch(struct perf_event *event)
1354{
1355 return armpmu_map_event(event, &krait_perf_map_no_branch,
1356 &krait_perf_cache_map, 0xFFFFF);
1357}
1358
1215static void armv7pmu_init(struct arm_pmu *cpu_pmu) 1359static void armv7pmu_init(struct arm_pmu *cpu_pmu)
1216{ 1360{
1217 cpu_pmu->handle_irq = armv7pmu_handle_irq; 1361 cpu_pmu->handle_irq = armv7pmu_handle_irq;
@@ -1283,6 +1427,21 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1283 cpu_pmu->set_event_filter = armv7pmu_set_event_filter; 1427 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1284 return 0; 1428 return 0;
1285} 1429}
1430
1431static int krait_pmu_init(struct arm_pmu *cpu_pmu)
1432{
1433 armv7pmu_init(cpu_pmu);
1434 cpu_pmu->name = "ARMv7 Krait";
1435 /* Some early versions of Krait don't support PC write events */
1436 if (of_property_read_bool(cpu_pmu->plat_device->dev.of_node,
1437 "qcom,no-pc-write"))
1438 cpu_pmu->map_event = krait_map_event_no_branch;
1439 else
1440 cpu_pmu->map_event = krait_map_event;
1441 cpu_pmu->num_events = armv7_read_num_pmnc_events();
1442 cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
1443 return 0;
1444}
1286#else 1445#else
1287static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) 1446static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
1288{ 1447{
@@ -1308,4 +1467,9 @@ static inline int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
1308{ 1467{
1309 return -ENODEV; 1468 return -ENODEV;
1310} 1469}
1470
1471static inline int krait_pmu_init(struct arm_pmu *cpu_pmu)
1472{
1473 return -ENODEV;
1474}
1311#endif /* CONFIG_CPU_V7 */ 1475#endif /* CONFIG_CPU_V7 */