^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) // Copyright (C) 2018 Hangzhou C-SKY Microsystems co.,ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/perf_event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #define CSKY_PMU_MAX_EVENTS 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define DEFAULT_COUNT_WIDTH 48
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define HPCR "<0, 0x0>" /* PMU Control reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define HPSPR "<0, 0x1>" /* Start PC reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define HPEPR "<0, 0x2>" /* End PC reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define HPSIR "<0, 0x3>" /* Soft Counter reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define HPCNTENR "<0, 0x4>" /* Count Enable reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define HPINTENR "<0, 0x5>" /* Interrupt Enable reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define HPOFSR "<0, 0x6>" /* Interrupt Status reg */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) /* The events for a given PMU register set. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct pmu_hw_events {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * The events that are active on the PMU for the given index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct perf_event *events[CSKY_PMU_MAX_EVENTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * A 1 bit for an index indicates that the counter is being used for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * an event. A 0 means that the counter can be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned long used_mask[BITS_TO_LONGS(CSKY_PMU_MAX_EVENTS)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static uint64_t (*hw_raw_read_mapping[CSKY_PMU_MAX_EVENTS])(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static void (*hw_raw_write_mapping[CSKY_PMU_MAX_EVENTS])(uint64_t val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static struct csky_pmu_t {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) struct pmu pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct pmu_hw_events __percpu *hw_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) struct platform_device *plat_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) uint32_t count_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) uint32_t hpcr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) u64 max_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) } csky_pmu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int csky_pmu_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define to_csky_pmu(p) (container_of(p, struct csky_pmu, pmu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define cprgr(reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned int tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) asm volatile("cprgr %0, "reg"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) : "=r"(tmp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) : "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define cpwgr(reg, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) asm volatile( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) "cpwgr %0, "reg"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) : "r"(val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) : "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define cprcr(reg) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) unsigned int tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) asm volatile("cprcr %0, "reg"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) : "=r"(tmp) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) : "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) tmp; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define cpwcr(reg, val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) asm volatile( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) "cpwcr %0, "reg"\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) : \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) : "r"(val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) : "memory"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) /* cycle counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static uint64_t csky_pmu_read_cc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) tmp = cprgr("<0, 0x3>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) lo = cprgr("<0, 0x2>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) hi = cprgr("<0, 0x3>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static void csky_pmu_write_cc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) cpwgr("<0, 0x2>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) cpwgr("<0, 0x3>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /* instruction counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) static uint64_t csky_pmu_read_ic(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) tmp = cprgr("<0, 0x5>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) lo = cprgr("<0, 0x4>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) hi = cprgr("<0, 0x5>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static void csky_pmu_write_ic(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) cpwgr("<0, 0x4>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) cpwgr("<0, 0x5>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* l1 icache access counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static uint64_t csky_pmu_read_icac(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) tmp = cprgr("<0, 0x7>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) lo = cprgr("<0, 0x6>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) hi = cprgr("<0, 0x7>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) static void csky_pmu_write_icac(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) cpwgr("<0, 0x6>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) cpwgr("<0, 0x7>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) /* l1 icache miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static uint64_t csky_pmu_read_icmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) tmp = cprgr("<0, 0x9>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) lo = cprgr("<0, 0x8>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) hi = cprgr("<0, 0x9>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void csky_pmu_write_icmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) cpwgr("<0, 0x8>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) cpwgr("<0, 0x9>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) /* l1 dcache access counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static uint64_t csky_pmu_read_dcac(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) tmp = cprgr("<0, 0xb>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) lo = cprgr("<0, 0xa>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) hi = cprgr("<0, 0xb>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static void csky_pmu_write_dcac(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) cpwgr("<0, 0xa>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) cpwgr("<0, 0xb>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /* l1 dcache miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static uint64_t csky_pmu_read_dcmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) tmp = cprgr("<0, 0xd>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) lo = cprgr("<0, 0xc>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) hi = cprgr("<0, 0xd>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static void csky_pmu_write_dcmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cpwgr("<0, 0xc>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) cpwgr("<0, 0xd>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* l2 cache access counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static uint64_t csky_pmu_read_l2ac(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) tmp = cprgr("<0, 0xf>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) lo = cprgr("<0, 0xe>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) hi = cprgr("<0, 0xf>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static void csky_pmu_write_l2ac(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) cpwgr("<0, 0xe>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) cpwgr("<0, 0xf>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* l2 cache miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static uint64_t csky_pmu_read_l2mc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) tmp = cprgr("<0, 0x11>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) lo = cprgr("<0, 0x10>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) hi = cprgr("<0, 0x11>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static void csky_pmu_write_l2mc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) cpwgr("<0, 0x10>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) cpwgr("<0, 0x11>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* I-UTLB miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static uint64_t csky_pmu_read_iutlbmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) tmp = cprgr("<0, 0x15>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) lo = cprgr("<0, 0x14>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) hi = cprgr("<0, 0x15>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) static void csky_pmu_write_iutlbmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) cpwgr("<0, 0x14>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) cpwgr("<0, 0x15>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /* D-UTLB miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) static uint64_t csky_pmu_read_dutlbmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) tmp = cprgr("<0, 0x17>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) lo = cprgr("<0, 0x16>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) hi = cprgr("<0, 0x17>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) static void csky_pmu_write_dutlbmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) cpwgr("<0, 0x16>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) cpwgr("<0, 0x17>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* JTLB miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static uint64_t csky_pmu_read_jtlbmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) tmp = cprgr("<0, 0x19>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) lo = cprgr("<0, 0x18>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) hi = cprgr("<0, 0x19>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) static void csky_pmu_write_jtlbmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) cpwgr("<0, 0x18>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) cpwgr("<0, 0x19>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /* software counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) static uint64_t csky_pmu_read_softc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) tmp = cprgr("<0, 0x1b>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) lo = cprgr("<0, 0x1a>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) hi = cprgr("<0, 0x1b>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static void csky_pmu_write_softc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) cpwgr("<0, 0x1a>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) cpwgr("<0, 0x1b>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* conditional branch mispredict counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static uint64_t csky_pmu_read_cbmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) tmp = cprgr("<0, 0x1d>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) lo = cprgr("<0, 0x1c>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) hi = cprgr("<0, 0x1d>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) static void csky_pmu_write_cbmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) cpwgr("<0, 0x1c>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) cpwgr("<0, 0x1d>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* conditional branch instruction counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) static uint64_t csky_pmu_read_cbic(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) tmp = cprgr("<0, 0x1f>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) lo = cprgr("<0, 0x1e>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) hi = cprgr("<0, 0x1f>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) static void csky_pmu_write_cbic(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) cpwgr("<0, 0x1e>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) cpwgr("<0, 0x1f>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /* indirect branch mispredict counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static uint64_t csky_pmu_read_ibmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) tmp = cprgr("<0, 0x21>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) lo = cprgr("<0, 0x20>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) hi = cprgr("<0, 0x21>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static void csky_pmu_write_ibmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) cpwgr("<0, 0x20>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) cpwgr("<0, 0x21>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* indirect branch instruction counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) static uint64_t csky_pmu_read_ibic(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) tmp = cprgr("<0, 0x23>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) lo = cprgr("<0, 0x22>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) hi = cprgr("<0, 0x23>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static void csky_pmu_write_ibic(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) cpwgr("<0, 0x22>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) cpwgr("<0, 0x23>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* LSU spec fail counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static uint64_t csky_pmu_read_lsfc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) tmp = cprgr("<0, 0x25>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) lo = cprgr("<0, 0x24>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) hi = cprgr("<0, 0x25>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) static void csky_pmu_write_lsfc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) cpwgr("<0, 0x24>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) cpwgr("<0, 0x25>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* store instruction counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) static uint64_t csky_pmu_read_sic(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) tmp = cprgr("<0, 0x27>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) lo = cprgr("<0, 0x26>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) hi = cprgr("<0, 0x27>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static void csky_pmu_write_sic(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) cpwgr("<0, 0x26>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) cpwgr("<0, 0x27>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* dcache read access counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) static uint64_t csky_pmu_read_dcrac(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) tmp = cprgr("<0, 0x29>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) lo = cprgr("<0, 0x28>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) hi = cprgr("<0, 0x29>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void csky_pmu_write_dcrac(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) cpwgr("<0, 0x28>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) cpwgr("<0, 0x29>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /* dcache read miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) static uint64_t csky_pmu_read_dcrmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) tmp = cprgr("<0, 0x2b>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) lo = cprgr("<0, 0x2a>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) hi = cprgr("<0, 0x2b>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) static void csky_pmu_write_dcrmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) cpwgr("<0, 0x2a>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) cpwgr("<0, 0x2b>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* dcache write access counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) static uint64_t csky_pmu_read_dcwac(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) tmp = cprgr("<0, 0x2d>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) lo = cprgr("<0, 0x2c>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) hi = cprgr("<0, 0x2d>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) static void csky_pmu_write_dcwac(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) cpwgr("<0, 0x2c>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) cpwgr("<0, 0x2d>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) /* dcache write miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) static uint64_t csky_pmu_read_dcwmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) tmp = cprgr("<0, 0x2f>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) lo = cprgr("<0, 0x2e>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) hi = cprgr("<0, 0x2f>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void csky_pmu_write_dcwmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) cpwgr("<0, 0x2e>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) cpwgr("<0, 0x2f>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* l2cache read access counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) static uint64_t csky_pmu_read_l2rac(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) tmp = cprgr("<0, 0x31>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) lo = cprgr("<0, 0x30>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) hi = cprgr("<0, 0x31>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) static void csky_pmu_write_l2rac(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) cpwgr("<0, 0x30>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) cpwgr("<0, 0x31>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) /* l2cache read miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static uint64_t csky_pmu_read_l2rmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) tmp = cprgr("<0, 0x33>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) lo = cprgr("<0, 0x32>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) hi = cprgr("<0, 0x33>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) static void csky_pmu_write_l2rmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) cpwgr("<0, 0x32>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) cpwgr("<0, 0x33>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) /* l2cache write access counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static uint64_t csky_pmu_read_l2wac(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) tmp = cprgr("<0, 0x35>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) lo = cprgr("<0, 0x34>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) hi = cprgr("<0, 0x35>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static void csky_pmu_write_l2wac(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) cpwgr("<0, 0x34>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) cpwgr("<0, 0x35>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) /* l2cache write miss counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) static uint64_t csky_pmu_read_l2wmc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) uint32_t lo, hi, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) uint64_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) tmp = cprgr("<0, 0x37>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) lo = cprgr("<0, 0x36>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) hi = cprgr("<0, 0x37>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) } while (hi != tmp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) result = (uint64_t) (hi) << 32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) result |= lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static void csky_pmu_write_l2wmc(uint64_t val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) cpwgr("<0, 0x36>", (uint32_t) val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) cpwgr("<0, 0x37>", (uint32_t) (val >> 32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) #define HW_OP_UNSUPPORTED 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) static const int csky_pmu_hw_map[PERF_COUNT_HW_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) [PERF_COUNT_HW_CPU_CYCLES] = 0x1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) [PERF_COUNT_HW_INSTRUCTIONS] = 0x2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) [PERF_COUNT_HW_CACHE_REFERENCES] = HW_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) [PERF_COUNT_HW_CACHE_MISSES] = HW_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0xf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) [PERF_COUNT_HW_BRANCH_MISSES] = 0xe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) [PERF_COUNT_HW_BUS_CYCLES] = HW_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) [PERF_COUNT_HW_REF_CPU_CYCLES] = HW_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) #define C(_x) PERF_COUNT_HW_CACHE_##_x
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) #define CACHE_OP_UNSUPPORTED 0xffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) static const int csky_pmu_cache_map[C(MAX)][C(OP_MAX)][C(RESULT_MAX)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) [C(L1D)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) #ifdef CONFIG_CPU_CK810
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) [C(RESULT_ACCESS)] = 0x5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) [C(RESULT_MISS)] = 0x6,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) [C(RESULT_ACCESS)] = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) [C(RESULT_MISS)] = 0x15,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) [C(RESULT_ACCESS)] = 0x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) [C(RESULT_MISS)] = 0x17,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) [C(L1I)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) [C(RESULT_ACCESS)] = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) [C(RESULT_MISS)] = 0x4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) [C(LL)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) #ifdef CONFIG_CPU_CK810
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) [C(RESULT_ACCESS)] = 0x7,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) [C(RESULT_MISS)] = 0x8,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) [C(RESULT_ACCESS)] = 0x18,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) [C(RESULT_MISS)] = 0x19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) [C(RESULT_ACCESS)] = 0x1a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) [C(RESULT_MISS)] = 0x1b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) [C(DTLB)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) #ifdef CONFIG_CPU_CK810
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) [C(RESULT_ACCESS)] = 0x14,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) [C(RESULT_MISS)] = 0xb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) [C(RESULT_ACCESS)] = 0x16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) [C(RESULT_MISS)] = 0xb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) [C(ITLB)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) #ifdef CONFIG_CPU_CK810
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) [C(RESULT_ACCESS)] = 0x3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) [C(RESULT_MISS)] = 0xa,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) [C(BPU)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) [C(NODE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) [C(OP_READ)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) [C(OP_WRITE)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) [C(OP_PREFETCH)] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int csky_pmu_event_set_period(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct hw_perf_event *hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) s64 left = local64_read(&hwc->period_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) s64 period = hwc->sample_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if (unlikely(left <= -period)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) left = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) local64_set(&hwc->period_left, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) hwc->last_period = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (unlikely(left <= 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) left += period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) local64_set(&hwc->period_left, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) hwc->last_period = period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) ret = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) if (left > (s64)csky_pmu.max_period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) left = csky_pmu.max_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * The hw event starts counting from this event offset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * mark it to be able to extract future "deltas":
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) local64_set(&hwc->prev_count, (u64)(-left));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (hw_raw_write_mapping[hwc->idx] != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) hw_raw_write_mapping[hwc->idx]((u64)(-left) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) csky_pmu.max_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) cpwcr(HPOFSR, ~BIT(hwc->idx) & cprcr(HPOFSR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) perf_event_update_userpage(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) static void csky_perf_event_update(struct perf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) struct hw_perf_event *hwc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) uint64_t prev_raw_count = local64_read(&hwc->prev_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * Sign extend count value to 64bit, otherwise delta calculation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * would be incorrect when overflow occurs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) uint64_t new_raw_count = sign_extend64(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) hw_raw_read_mapping[hwc->idx](), csky_pmu.count_width - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) int64_t delta = new_raw_count - prev_raw_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) * We aren't afraid of hwc->prev_count changing beneath our feet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * because there's no way for us to re-enter this function anytime.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) local64_set(&hwc->prev_count, new_raw_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) local64_add(delta, &event->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) local64_sub(delta, &hwc->period_left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static void csky_pmu_reset(void *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) cpwcr(HPCR, BIT(31) | BIT(30) | BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) static void csky_pmu_read(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) csky_perf_event_update(event, &event->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) static int csky_pmu_cache_event(u64 config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) unsigned int cache_type, cache_op, cache_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) cache_type = (config >> 0) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) cache_op = (config >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) cache_result = (config >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (cache_type >= PERF_COUNT_HW_CACHE_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (cache_op >= PERF_COUNT_HW_CACHE_OP_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) if (cache_result >= PERF_COUNT_HW_CACHE_RESULT_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return csky_pmu_cache_map[cache_type][cache_op][cache_result];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static int csky_pmu_event_init(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) struct hw_perf_event *hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) switch (event->attr.type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) case PERF_TYPE_HARDWARE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) if (event->attr.config >= PERF_COUNT_HW_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) ret = csky_pmu_hw_map[event->attr.config];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (ret == HW_OP_UNSUPPORTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) hwc->idx = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) case PERF_TYPE_HW_CACHE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) ret = csky_pmu_cache_event(event->attr.config);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (ret == CACHE_OP_UNSUPPORTED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) hwc->idx = ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) case PERF_TYPE_RAW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (hw_raw_read_mapping[event->attr.config] == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) hwc->idx = event->attr.config;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) if (event->attr.exclude_user)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) csky_pmu.hpcr = BIT(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) else if (event->attr.exclude_kernel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) csky_pmu.hpcr = BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) csky_pmu.hpcr = BIT(2) | BIT(3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) csky_pmu.hpcr |= BIT(1) | BIT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* starts all counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static void csky_pmu_enable(struct pmu *pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) cpwcr(HPCR, csky_pmu.hpcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /* stops all counters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) static void csky_pmu_disable(struct pmu *pmu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) cpwcr(HPCR, BIT(1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static void csky_pmu_start(struct perf_event *event, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) unsigned long flg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) struct hw_perf_event *hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) int idx = hwc->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (WARN_ON_ONCE(idx == -1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (flags & PERF_EF_RELOAD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) WARN_ON_ONCE(!(hwc->state & PERF_HES_UPTODATE));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) hwc->state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) csky_pmu_event_set_period(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) local_irq_save(flg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) cpwcr(HPINTENR, BIT(idx) | cprcr(HPINTENR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) cpwcr(HPCNTENR, BIT(idx) | cprcr(HPCNTENR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) local_irq_restore(flg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void csky_pmu_stop_event(struct perf_event *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) unsigned long flg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) struct hw_perf_event *hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) int idx = hwc->idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) local_irq_save(flg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) cpwcr(HPINTENR, ~BIT(idx) & cprcr(HPINTENR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) cpwcr(HPCNTENR, ~BIT(idx) & cprcr(HPCNTENR));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) local_irq_restore(flg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) static void csky_pmu_stop(struct perf_event *event, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (!(event->hw.state & PERF_HES_STOPPED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) csky_pmu_stop_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) event->hw.state |= PERF_HES_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if ((flags & PERF_EF_UPDATE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) !(event->hw.state & PERF_HES_UPTODATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) csky_perf_event_update(event, &event->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) event->hw.state |= PERF_HES_UPTODATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static void csky_pmu_del(struct perf_event *event, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct pmu_hw_events *hw_events = this_cpu_ptr(csky_pmu.hw_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct hw_perf_event *hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) csky_pmu_stop(event, PERF_EF_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) hw_events->events[hwc->idx] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) perf_event_update_userpage(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* allocate hardware counter and optionally start counting */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) static int csky_pmu_add(struct perf_event *event, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct pmu_hw_events *hw_events = this_cpu_ptr(csky_pmu.hw_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) struct hw_perf_event *hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) hw_events->events[hwc->idx] = event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (flags & PERF_EF_START)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) csky_pmu_start(event, PERF_EF_RELOAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) perf_event_update_userpage(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) static irqreturn_t csky_pmu_handle_irq(int irq_num, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct perf_sample_data data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct pmu_hw_events *cpuc = this_cpu_ptr(csky_pmu.hw_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) struct pt_regs *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) * Did an overflow occur?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (!cprcr(HPOFSR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) * Handle the counter(s) overflow(s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) regs = get_irq_regs();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) csky_pmu_disable(&csky_pmu.pmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) for (idx = 0; idx < CSKY_PMU_MAX_EVENTS; ++idx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) struct perf_event *event = cpuc->events[idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) struct hw_perf_event *hwc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) /* Ignore if we don't have an event. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (!event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) * We have a single interrupt for all counters. Check that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) * each counter has overflowed before we process it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) if (!(cprcr(HPOFSR) & BIT(idx)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) hwc = &event->hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) csky_perf_event_update(event, &event->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) perf_sample_data_init(&data, 0, hwc->last_period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) csky_pmu_event_set_period(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (perf_event_overflow(event, &data, regs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) csky_pmu_stop_event(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) csky_pmu_enable(&csky_pmu.pmu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * Handle the pending perf events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * Note: this call *must* be run with interrupts disabled. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) * platforms that can have the PMU interrupts raised as an NMI, this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) * will not work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) irq_work_run();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static int csky_pmu_request_irq(irq_handler_t handler)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) int err, irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct platform_device *pmu_device = csky_pmu.plat_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (!pmu_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) irqs = min(pmu_device->num_resources, num_possible_cpus());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) if (irqs < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) pr_err("no irqs for PMUs defined\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) csky_pmu_irq = platform_get_irq(pmu_device, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (csky_pmu_irq < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) err = request_percpu_irq(csky_pmu_irq, handler, "csky-pmu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) this_cpu_ptr(csky_pmu.hw_events));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) pr_err("unable to request IRQ%d for CSKY PMU counters\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) csky_pmu_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static void csky_pmu_free_irq(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) int irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) struct platform_device *pmu_device = csky_pmu.plat_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) irq = platform_get_irq(pmu_device, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) if (irq >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) free_percpu_irq(irq, this_cpu_ptr(csky_pmu.hw_events));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) int init_hw_perf_events(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) csky_pmu.hw_events = alloc_percpu_gfp(struct pmu_hw_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (!csky_pmu.hw_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) pr_info("failed to allocate per-cpu PMU data.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) csky_pmu.pmu = (struct pmu) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) .pmu_enable = csky_pmu_enable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) .pmu_disable = csky_pmu_disable,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) .event_init = csky_pmu_event_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) .add = csky_pmu_add,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) .del = csky_pmu_del,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) .start = csky_pmu_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) .stop = csky_pmu_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) .read = csky_pmu_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) memset((void *)hw_raw_read_mapping, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) sizeof(hw_raw_read_mapping[CSKY_PMU_MAX_EVENTS]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) hw_raw_read_mapping[0x1] = csky_pmu_read_cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) hw_raw_read_mapping[0x2] = csky_pmu_read_ic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) hw_raw_read_mapping[0x3] = csky_pmu_read_icac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) hw_raw_read_mapping[0x4] = csky_pmu_read_icmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) hw_raw_read_mapping[0x5] = csky_pmu_read_dcac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) hw_raw_read_mapping[0x6] = csky_pmu_read_dcmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) hw_raw_read_mapping[0x7] = csky_pmu_read_l2ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) hw_raw_read_mapping[0x8] = csky_pmu_read_l2mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) hw_raw_read_mapping[0xa] = csky_pmu_read_iutlbmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) hw_raw_read_mapping[0xb] = csky_pmu_read_dutlbmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) hw_raw_read_mapping[0xc] = csky_pmu_read_jtlbmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) hw_raw_read_mapping[0xd] = csky_pmu_read_softc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) hw_raw_read_mapping[0xe] = csky_pmu_read_cbmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) hw_raw_read_mapping[0xf] = csky_pmu_read_cbic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) hw_raw_read_mapping[0x10] = csky_pmu_read_ibmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) hw_raw_read_mapping[0x11] = csky_pmu_read_ibic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) hw_raw_read_mapping[0x12] = csky_pmu_read_lsfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) hw_raw_read_mapping[0x13] = csky_pmu_read_sic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) hw_raw_read_mapping[0x14] = csky_pmu_read_dcrac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) hw_raw_read_mapping[0x15] = csky_pmu_read_dcrmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) hw_raw_read_mapping[0x16] = csky_pmu_read_dcwac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) hw_raw_read_mapping[0x17] = csky_pmu_read_dcwmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) hw_raw_read_mapping[0x18] = csky_pmu_read_l2rac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) hw_raw_read_mapping[0x19] = csky_pmu_read_l2rmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) hw_raw_read_mapping[0x1a] = csky_pmu_read_l2wac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) hw_raw_read_mapping[0x1b] = csky_pmu_read_l2wmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) memset((void *)hw_raw_write_mapping, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) sizeof(hw_raw_write_mapping[CSKY_PMU_MAX_EVENTS]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) hw_raw_write_mapping[0x1] = csky_pmu_write_cc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) hw_raw_write_mapping[0x2] = csky_pmu_write_ic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) hw_raw_write_mapping[0x3] = csky_pmu_write_icac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) hw_raw_write_mapping[0x4] = csky_pmu_write_icmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) hw_raw_write_mapping[0x5] = csky_pmu_write_dcac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) hw_raw_write_mapping[0x6] = csky_pmu_write_dcmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) hw_raw_write_mapping[0x7] = csky_pmu_write_l2ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) hw_raw_write_mapping[0x8] = csky_pmu_write_l2mc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) hw_raw_write_mapping[0xa] = csky_pmu_write_iutlbmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) hw_raw_write_mapping[0xb] = csky_pmu_write_dutlbmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) hw_raw_write_mapping[0xc] = csky_pmu_write_jtlbmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) hw_raw_write_mapping[0xd] = csky_pmu_write_softc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) hw_raw_write_mapping[0xe] = csky_pmu_write_cbmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) hw_raw_write_mapping[0xf] = csky_pmu_write_cbic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) hw_raw_write_mapping[0x10] = csky_pmu_write_ibmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) hw_raw_write_mapping[0x11] = csky_pmu_write_ibic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) hw_raw_write_mapping[0x12] = csky_pmu_write_lsfc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) hw_raw_write_mapping[0x13] = csky_pmu_write_sic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) hw_raw_write_mapping[0x14] = csky_pmu_write_dcrac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) hw_raw_write_mapping[0x15] = csky_pmu_write_dcrmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) hw_raw_write_mapping[0x16] = csky_pmu_write_dcwac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) hw_raw_write_mapping[0x17] = csky_pmu_write_dcwmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) hw_raw_write_mapping[0x18] = csky_pmu_write_l2rac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) hw_raw_write_mapping[0x19] = csky_pmu_write_l2rmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) hw_raw_write_mapping[0x1a] = csky_pmu_write_l2wac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) hw_raw_write_mapping[0x1b] = csky_pmu_write_l2wmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) static int csky_pmu_starting_cpu(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) enable_percpu_irq(csky_pmu_irq, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static int csky_pmu_dying_cpu(unsigned int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) disable_percpu_irq(csky_pmu_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) int csky_pmu_device_probe(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) const struct of_device_id *of_table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) struct device_node *node = pdev->dev.of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) ret = init_hw_perf_events();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) pr_notice("[perf] failed to probe PMU!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (of_property_read_u32(node, "count-width",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) &csky_pmu.count_width)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) csky_pmu.count_width = DEFAULT_COUNT_WIDTH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) csky_pmu.max_period = BIT_ULL(csky_pmu.count_width) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) csky_pmu.plat_device = pdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) /* Ensure the PMU has sane values out of reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) on_each_cpu(csky_pmu_reset, &csky_pmu, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ret = csky_pmu_request_irq(csky_pmu_handle_irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) csky_pmu.pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) pr_notice("[perf] PMU request irq fail!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) ret = cpuhp_setup_state(CPUHP_AP_PERF_ONLINE, "AP_PERF_ONLINE",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) csky_pmu_starting_cpu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) csky_pmu_dying_cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) csky_pmu_free_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) free_percpu(csky_pmu.hw_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) ret = perf_pmu_register(&csky_pmu.pmu, "cpu", PERF_TYPE_RAW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) csky_pmu_free_irq();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) free_percpu(csky_pmu.hw_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) static const struct of_device_id csky_pmu_of_device_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) {.compatible = "csky,csky-pmu"},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) {},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) static int csky_pmu_dev_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) return csky_pmu_device_probe(pdev, csky_pmu_of_device_ids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) static struct platform_driver csky_pmu_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) .name = "csky-pmu",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) .of_match_table = csky_pmu_of_device_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) .probe = csky_pmu_dev_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) static int __init csky_pmu_probe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) ret = platform_driver_register(&csky_pmu_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) pr_notice("[perf] PMU initialization failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) pr_notice("[perf] PMU initialization done\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) device_initcall(csky_pmu_probe);