diff options
author | Huacai Chen <chenhc@lemote.com> | 2015-03-28 22:54:08 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2015-04-01 11:22:17 -0400 |
commit | f14ceff75545f9a1e62430fe9cc796208569b972 (patch) | |
tree | cccf443f7d4fc6bc7eedbfcaf4d2abe5fb990745 /arch/mips/kernel | |
parent | a2e50f53d535fa885a432fb9fc3e3ca5ed97364c (diff) |
MIPS: perf: Add hardware perf events support for Loongson-3
This patch enable hardware performance counter support for Loongson-3's
perf events.
Signed-off-by: Huacai Chen <chenhc@lemote.com>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/9618/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/perf_event_mipsxx.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 192e7f59245e..cc1b6fadf089 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -825,6 +825,13 @@ static const struct mips_perf_event mipsxxcore_event_map2 | |||
825 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T }, | 825 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T }, |
826 | }; | 826 | }; |
827 | 827 | ||
828 | static const struct mips_perf_event loongson3_event_map[PERF_COUNT_HW_MAX] = { | ||
829 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN }, | ||
830 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, CNTR_ODD }, | ||
831 | [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x01, CNTR_EVEN }, | ||
832 | [PERF_COUNT_HW_BRANCH_MISSES] = { 0x01, CNTR_ODD }, | ||
833 | }; | ||
834 | |||
828 | static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = { | 835 | static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = { |
829 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL }, | 836 | [PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL }, |
830 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x03, CNTR_ALL }, | 837 | [PERF_COUNT_HW_INSTRUCTIONS] = { 0x03, CNTR_ALL }, |
@@ -1008,6 +1015,61 @@ static const struct mips_perf_event mipsxxcore_cache_map2 | |||
1008 | }, | 1015 | }, |
1009 | }; | 1016 | }; |
1010 | 1017 | ||
1018 | static const struct mips_perf_event loongson3_cache_map | ||
1019 | [PERF_COUNT_HW_CACHE_MAX] | ||
1020 | [PERF_COUNT_HW_CACHE_OP_MAX] | ||
1021 | [PERF_COUNT_HW_CACHE_RESULT_MAX] = { | ||
1022 | [C(L1D)] = { | ||
1023 | /* | ||
1024 | * Like some other architectures (e.g. ARM), the performance | ||
1025 | * counters don't differentiate between read and write | ||
1026 | * accesses/misses, so this isn't strictly correct, but it's the | ||
1027 | * best we can do. Writes and reads get combined. | ||
1028 | */ | ||
1029 | [C(OP_READ)] = { | ||
1030 | [C(RESULT_MISS)] = { 0x04, CNTR_ODD }, | ||
1031 | }, | ||
1032 | [C(OP_WRITE)] = { | ||
1033 | [C(RESULT_MISS)] = { 0x04, CNTR_ODD }, | ||
1034 | }, | ||
1035 | }, | ||
1036 | [C(L1I)] = { | ||
1037 | [C(OP_READ)] = { | ||
1038 | [C(RESULT_MISS)] = { 0x04, CNTR_EVEN }, | ||
1039 | }, | ||
1040 | [C(OP_WRITE)] = { | ||
1041 | [C(RESULT_MISS)] = { 0x04, CNTR_EVEN }, | ||
1042 | }, | ||
1043 | }, | ||
1044 | [C(DTLB)] = { | ||
1045 | [C(OP_READ)] = { | ||
1046 | [C(RESULT_MISS)] = { 0x09, CNTR_ODD }, | ||
1047 | }, | ||
1048 | [C(OP_WRITE)] = { | ||
1049 | [C(RESULT_MISS)] = { 0x09, CNTR_ODD }, | ||
1050 | }, | ||
1051 | }, | ||
1052 | [C(ITLB)] = { | ||
1053 | [C(OP_READ)] = { | ||
1054 | [C(RESULT_MISS)] = { 0x0c, CNTR_ODD }, | ||
1055 | }, | ||
1056 | [C(OP_WRITE)] = { | ||
1057 | [C(RESULT_MISS)] = { 0x0c, CNTR_ODD }, | ||
1058 | }, | ||
1059 | }, | ||
1060 | [C(BPU)] = { | ||
1061 | /* Using the same code for *HW_BRANCH* */ | ||
1062 | [C(OP_READ)] = { | ||
1063 | [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN }, | ||
1064 | [C(RESULT_MISS)] = { 0x02, CNTR_ODD }, | ||
1065 | }, | ||
1066 | [C(OP_WRITE)] = { | ||
1067 | [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN }, | ||
1068 | [C(RESULT_MISS)] = { 0x02, CNTR_ODD }, | ||
1069 | }, | ||
1070 | }, | ||
1071 | }; | ||
1072 | |||
1011 | /* BMIPS5000 */ | 1073 | /* BMIPS5000 */ |
1012 | static const struct mips_perf_event bmips5000_cache_map | 1074 | static const struct mips_perf_event bmips5000_cache_map |
1013 | [PERF_COUNT_HW_CACHE_MAX] | 1075 | [PERF_COUNT_HW_CACHE_MAX] |
@@ -1542,6 +1604,10 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) | |||
1542 | else | 1604 | else |
1543 | raw_event.cntr_mask = | 1605 | raw_event.cntr_mask = |
1544 | raw_id > 127 ? CNTR_ODD : CNTR_EVEN; | 1606 | raw_id > 127 ? CNTR_ODD : CNTR_EVEN; |
1607 | break; | ||
1608 | case CPU_LOONGSON3: | ||
1609 | raw_event.cntr_mask = raw_id > 127 ? CNTR_ODD : CNTR_EVEN; | ||
1610 | break; | ||
1545 | } | 1611 | } |
1546 | 1612 | ||
1547 | raw_event.event_id = base_id; | 1613 | raw_event.event_id = base_id; |
@@ -1671,6 +1737,11 @@ init_hw_perf_events(void) | |||
1671 | mipspmu.general_event_map = &mipsxxcore_event_map; | 1737 | mipspmu.general_event_map = &mipsxxcore_event_map; |
1672 | mipspmu.cache_event_map = &mipsxxcore_cache_map; | 1738 | mipspmu.cache_event_map = &mipsxxcore_cache_map; |
1673 | break; | 1739 | break; |
1740 | case CPU_LOONGSON3: | ||
1741 | mipspmu.name = "mips/loongson3"; | ||
1742 | mipspmu.general_event_map = &loongson3_event_map; | ||
1743 | mipspmu.cache_event_map = &loongson3_cache_map; | ||
1744 | break; | ||
1674 | case CPU_CAVIUM_OCTEON: | 1745 | case CPU_CAVIUM_OCTEON: |
1675 | case CPU_CAVIUM_OCTEON_PLUS: | 1746 | case CPU_CAVIUM_OCTEON_PLUS: |
1676 | case CPU_CAVIUM_OCTEON2: | 1747 | case CPU_CAVIUM_OCTEON2: |