diff options
| -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; |
