Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Driver for FPGA Management Engine (FME) Global Performance Reporting
0004  *
0005  * Copyright 2019 Intel Corporation, Inc.
0006  *
0007  * Authors:
0008  *   Kang Luwei <luwei.kang@intel.com>
0009  *   Xiao Guangrong <guangrong.xiao@linux.intel.com>
0010  *   Wu Hao <hao.wu@intel.com>
0011  *   Xu Yilun <yilun.xu@intel.com>
0012  *   Joseph Grecco <joe.grecco@intel.com>
0013  *   Enno Luebbers <enno.luebbers@intel.com>
0014  *   Tim Whisonant <tim.whisonant@intel.com>
0015  *   Ananda Ravuri <ananda.ravuri@intel.com>
0016  *   Mitchel, Henry <henry.mitchel@intel.com>
0017  */
0018 
0019 #include <linux/perf_event.h>
0020 #include "dfl.h"
0021 #include "dfl-fme.h"
0022 
0023 /*
0024  * Performance Counter Registers for Cache.
0025  *
0026  * Cache Events are listed below as CACHE_EVNT_*.
0027  */
0028 #define CACHE_CTRL          0x8
0029 #define CACHE_RESET_CNTR        BIT_ULL(0)
0030 #define CACHE_FREEZE_CNTR       BIT_ULL(8)
0031 #define CACHE_CTRL_EVNT         GENMASK_ULL(19, 16)
0032 #define CACHE_EVNT_RD_HIT       0x0
0033 #define CACHE_EVNT_WR_HIT       0x1
0034 #define CACHE_EVNT_RD_MISS      0x2
0035 #define CACHE_EVNT_WR_MISS      0x3
0036 #define CACHE_EVNT_RSVD         0x4
0037 #define CACHE_EVNT_HOLD_REQ     0x5
0038 #define CACHE_EVNT_DATA_WR_PORT_CONTEN  0x6
0039 #define CACHE_EVNT_TAG_WR_PORT_CONTEN   0x7
0040 #define CACHE_EVNT_TX_REQ_STALL     0x8
0041 #define CACHE_EVNT_RX_REQ_STALL     0x9
0042 #define CACHE_EVNT_EVICTIONS        0xa
0043 #define CACHE_EVNT_MAX          CACHE_EVNT_EVICTIONS
0044 #define CACHE_CHANNEL_SEL       BIT_ULL(20)
0045 #define CACHE_CHANNEL_RD        0
0046 #define CACHE_CHANNEL_WR        1
0047 #define CACHE_CNTR0         0x10
0048 #define CACHE_CNTR1         0x18
0049 #define CACHE_CNTR_EVNT_CNTR        GENMASK_ULL(47, 0)
0050 #define CACHE_CNTR_EVNT         GENMASK_ULL(63, 60)
0051 
0052 /*
0053  * Performance Counter Registers for Fabric.
0054  *
0055  * Fabric Events are listed below as FAB_EVNT_*
0056  */
0057 #define FAB_CTRL            0x20
0058 #define FAB_RESET_CNTR          BIT_ULL(0)
0059 #define FAB_FREEZE_CNTR         BIT_ULL(8)
0060 #define FAB_CTRL_EVNT           GENMASK_ULL(19, 16)
0061 #define FAB_EVNT_PCIE0_RD       0x0
0062 #define FAB_EVNT_PCIE0_WR       0x1
0063 #define FAB_EVNT_PCIE1_RD       0x2
0064 #define FAB_EVNT_PCIE1_WR       0x3
0065 #define FAB_EVNT_UPI_RD         0x4
0066 #define FAB_EVNT_UPI_WR         0x5
0067 #define FAB_EVNT_MMIO_RD        0x6
0068 #define FAB_EVNT_MMIO_WR        0x7
0069 #define FAB_EVNT_MAX            FAB_EVNT_MMIO_WR
0070 #define FAB_PORT_ID         GENMASK_ULL(21, 20)
0071 #define FAB_PORT_FILTER         BIT_ULL(23)
0072 #define FAB_PORT_FILTER_DISABLE     0
0073 #define FAB_PORT_FILTER_ENABLE      1
0074 #define FAB_CNTR            0x28
0075 #define FAB_CNTR_EVNT_CNTR      GENMASK_ULL(59, 0)
0076 #define FAB_CNTR_EVNT           GENMASK_ULL(63, 60)
0077 
0078 /*
0079  * Performance Counter Registers for Clock.
0080  *
0081  * Clock Counter can't be reset or frozen by SW.
0082  */
0083 #define CLK_CNTR            0x30
0084 #define BASIC_EVNT_CLK          0x0
0085 #define BASIC_EVNT_MAX          BASIC_EVNT_CLK
0086 
0087 /*
0088  * Performance Counter Registers for IOMMU / VT-D.
0089  *
0090  * VT-D Events are listed below as VTD_EVNT_* and VTD_SIP_EVNT_*
0091  */
0092 #define VTD_CTRL            0x38
0093 #define VTD_RESET_CNTR          BIT_ULL(0)
0094 #define VTD_FREEZE_CNTR         BIT_ULL(8)
0095 #define VTD_CTRL_EVNT           GENMASK_ULL(19, 16)
0096 #define VTD_EVNT_AFU_MEM_RD_TRANS   0x0
0097 #define VTD_EVNT_AFU_MEM_WR_TRANS   0x1
0098 #define VTD_EVNT_AFU_DEVTLB_RD_HIT  0x2
0099 #define VTD_EVNT_AFU_DEVTLB_WR_HIT  0x3
0100 #define VTD_EVNT_DEVTLB_4K_FILL     0x4
0101 #define VTD_EVNT_DEVTLB_2M_FILL     0x5
0102 #define VTD_EVNT_DEVTLB_1G_FILL     0x6
0103 #define VTD_EVNT_MAX            VTD_EVNT_DEVTLB_1G_FILL
0104 #define VTD_CNTR            0x40
0105 #define VTD_CNTR_EVNT_CNTR      GENMASK_ULL(47, 0)
0106 #define VTD_CNTR_EVNT           GENMASK_ULL(63, 60)
0107 
0108 #define VTD_SIP_CTRL            0x48
0109 #define VTD_SIP_RESET_CNTR      BIT_ULL(0)
0110 #define VTD_SIP_FREEZE_CNTR     BIT_ULL(8)
0111 #define VTD_SIP_CTRL_EVNT       GENMASK_ULL(19, 16)
0112 #define VTD_SIP_EVNT_IOTLB_4K_HIT   0x0
0113 #define VTD_SIP_EVNT_IOTLB_2M_HIT   0x1
0114 #define VTD_SIP_EVNT_IOTLB_1G_HIT   0x2
0115 #define VTD_SIP_EVNT_SLPWC_L3_HIT   0x3
0116 #define VTD_SIP_EVNT_SLPWC_L4_HIT   0x4
0117 #define VTD_SIP_EVNT_RCC_HIT        0x5
0118 #define VTD_SIP_EVNT_IOTLB_4K_MISS  0x6
0119 #define VTD_SIP_EVNT_IOTLB_2M_MISS  0x7
0120 #define VTD_SIP_EVNT_IOTLB_1G_MISS  0x8
0121 #define VTD_SIP_EVNT_SLPWC_L3_MISS  0x9
0122 #define VTD_SIP_EVNT_SLPWC_L4_MISS  0xa
0123 #define VTD_SIP_EVNT_RCC_MISS       0xb
0124 #define VTD_SIP_EVNT_MAX        VTD_SIP_EVNT_SLPWC_L4_MISS
0125 #define VTD_SIP_CNTR            0X50
0126 #define VTD_SIP_CNTR_EVNT_CNTR      GENMASK_ULL(47, 0)
0127 #define VTD_SIP_CNTR_EVNT       GENMASK_ULL(63, 60)
0128 
0129 #define PERF_TIMEOUT            30
0130 
0131 #define PERF_MAX_PORT_NUM       1U
0132 
0133 /**
0134  * struct fme_perf_priv - priv data structure for fme perf driver
0135  *
0136  * @dev: parent device.
0137  * @ioaddr: mapped base address of mmio region.
0138  * @pmu: pmu data structure for fme perf counters.
0139  * @id: id of this fme performance report private feature.
0140  * @fab_users: current user number on fabric counters.
0141  * @fab_port_id: used to indicate current working mode of fabric counters.
0142  * @fab_lock: lock to protect fabric counters working mode.
0143  * @cpu: active CPU to which the PMU is bound for accesses.
0144  * @cpuhp_node: node for CPU hotplug notifier link.
0145  * @cpuhp_state: state for CPU hotplug notification;
0146  */
0147 struct fme_perf_priv {
0148     struct device *dev;
0149     void __iomem *ioaddr;
0150     struct pmu pmu;
0151     u16 id;
0152 
0153     u32 fab_users;
0154     u32 fab_port_id;
0155     spinlock_t fab_lock;
0156 
0157     unsigned int cpu;
0158     struct hlist_node node;
0159     enum cpuhp_state cpuhp_state;
0160 };
0161 
0162 /**
0163  * struct fme_perf_event_ops - callbacks for fme perf events
0164  *
0165  * @event_init: callback invoked during event init.
0166  * @event_destroy: callback invoked during event destroy.
0167  * @read_counter: callback to read hardware counters.
0168  */
0169 struct fme_perf_event_ops {
0170     int (*event_init)(struct fme_perf_priv *priv, u32 event, u32 portid);
0171     void (*event_destroy)(struct fme_perf_priv *priv, u32 event,
0172                   u32 portid);
0173     u64 (*read_counter)(struct fme_perf_priv *priv, u32 event, u32 portid);
0174 };
0175 
0176 #define to_fme_perf_priv(_pmu)  container_of(_pmu, struct fme_perf_priv, pmu)
0177 
0178 static ssize_t cpumask_show(struct device *dev,
0179                 struct device_attribute *attr, char *buf)
0180 {
0181     struct pmu *pmu = dev_get_drvdata(dev);
0182     struct fme_perf_priv *priv;
0183 
0184     priv = to_fme_perf_priv(pmu);
0185 
0186     return cpumap_print_to_pagebuf(true, buf, cpumask_of(priv->cpu));
0187 }
0188 static DEVICE_ATTR_RO(cpumask);
0189 
0190 static struct attribute *fme_perf_cpumask_attrs[] = {
0191     &dev_attr_cpumask.attr,
0192     NULL,
0193 };
0194 
0195 static const struct attribute_group fme_perf_cpumask_group = {
0196     .attrs = fme_perf_cpumask_attrs,
0197 };
0198 
0199 #define FME_EVENT_MASK      GENMASK_ULL(11, 0)
0200 #define FME_EVENT_SHIFT     0
0201 #define FME_EVTYPE_MASK     GENMASK_ULL(15, 12)
0202 #define FME_EVTYPE_SHIFT    12
0203 #define FME_EVTYPE_BASIC    0
0204 #define FME_EVTYPE_CACHE    1
0205 #define FME_EVTYPE_FABRIC   2
0206 #define FME_EVTYPE_VTD      3
0207 #define FME_EVTYPE_VTD_SIP  4
0208 #define FME_EVTYPE_MAX      FME_EVTYPE_VTD_SIP
0209 #define FME_PORTID_MASK     GENMASK_ULL(23, 16)
0210 #define FME_PORTID_SHIFT    16
0211 #define FME_PORTID_ROOT     (0xffU)
0212 
0213 #define get_event(_config)  FIELD_GET(FME_EVENT_MASK, _config)
0214 #define get_evtype(_config) FIELD_GET(FME_EVTYPE_MASK, _config)
0215 #define get_portid(_config) FIELD_GET(FME_PORTID_MASK, _config)
0216 
0217 PMU_FORMAT_ATTR(event,      "config:0-11");
0218 PMU_FORMAT_ATTR(evtype,     "config:12-15");
0219 PMU_FORMAT_ATTR(portid,     "config:16-23");
0220 
0221 static struct attribute *fme_perf_format_attrs[] = {
0222     &format_attr_event.attr,
0223     &format_attr_evtype.attr,
0224     &format_attr_portid.attr,
0225     NULL,
0226 };
0227 
0228 static const struct attribute_group fme_perf_format_group = {
0229     .name = "format",
0230     .attrs = fme_perf_format_attrs,
0231 };
0232 
0233 /*
0234  * There are no default events, but we need to create
0235  * "events" group (with empty attrs) before updating
0236  * it with detected events (using pmu->attr_update).
0237  */
0238 static struct attribute *fme_perf_events_attrs_empty[] = {
0239     NULL,
0240 };
0241 
0242 static const struct attribute_group fme_perf_events_group = {
0243     .name = "events",
0244     .attrs = fme_perf_events_attrs_empty,
0245 };
0246 
0247 static const struct attribute_group *fme_perf_groups[] = {
0248     &fme_perf_format_group,
0249     &fme_perf_cpumask_group,
0250     &fme_perf_events_group,
0251     NULL,
0252 };
0253 
0254 static bool is_portid_root(u32 portid)
0255 {
0256     return portid == FME_PORTID_ROOT;
0257 }
0258 
0259 static bool is_portid_port(u32 portid)
0260 {
0261     return portid < PERF_MAX_PORT_NUM;
0262 }
0263 
0264 static bool is_portid_root_or_port(u32 portid)
0265 {
0266     return is_portid_root(portid) || is_portid_port(portid);
0267 }
0268 
0269 static u64 fme_read_perf_cntr_reg(void __iomem *addr)
0270 {
0271     u32 low;
0272     u64 v;
0273 
0274     /*
0275      * For 64bit counter registers, the counter may increases and carries
0276      * out of bit [31] between 2 32bit reads. So add extra reads to help
0277      * to prevent this issue. This only happens in platforms which don't
0278      * support 64bit read - readq is split into 2 readl.
0279      */
0280     do {
0281         v = readq(addr);
0282         low = readl(addr);
0283     } while (((u32)v) > low);
0284 
0285     return v;
0286 }
0287 
0288 static int basic_event_init(struct fme_perf_priv *priv, u32 event, u32 portid)
0289 {
0290     if (event <= BASIC_EVNT_MAX && is_portid_root(portid))
0291         return 0;
0292 
0293     return -EINVAL;
0294 }
0295 
0296 static u64 basic_read_event_counter(struct fme_perf_priv *priv,
0297                     u32 event, u32 portid)
0298 {
0299     void __iomem *base = priv->ioaddr;
0300 
0301     return fme_read_perf_cntr_reg(base + CLK_CNTR);
0302 }
0303 
0304 static int cache_event_init(struct fme_perf_priv *priv, u32 event, u32 portid)
0305 {
0306     if (priv->id == FME_FEATURE_ID_GLOBAL_IPERF &&
0307         event <= CACHE_EVNT_MAX && is_portid_root(portid))
0308         return 0;
0309 
0310     return -EINVAL;
0311 }
0312 
0313 static u64 cache_read_event_counter(struct fme_perf_priv *priv,
0314                     u32 event, u32 portid)
0315 {
0316     void __iomem *base = priv->ioaddr;
0317     u64 v, count;
0318     u8 channel;
0319 
0320     if (event == CACHE_EVNT_WR_HIT || event == CACHE_EVNT_WR_MISS ||
0321         event == CACHE_EVNT_DATA_WR_PORT_CONTEN ||
0322         event == CACHE_EVNT_TAG_WR_PORT_CONTEN)
0323         channel = CACHE_CHANNEL_WR;
0324     else
0325         channel = CACHE_CHANNEL_RD;
0326 
0327     /* set channel access type and cache event code. */
0328     v = readq(base + CACHE_CTRL);
0329     v &= ~(CACHE_CHANNEL_SEL | CACHE_CTRL_EVNT);
0330     v |= FIELD_PREP(CACHE_CHANNEL_SEL, channel);
0331     v |= FIELD_PREP(CACHE_CTRL_EVNT, event);
0332     writeq(v, base + CACHE_CTRL);
0333 
0334     if (readq_poll_timeout_atomic(base + CACHE_CNTR0, v,
0335                       FIELD_GET(CACHE_CNTR_EVNT, v) == event,
0336                       1, PERF_TIMEOUT)) {
0337         dev_err(priv->dev, "timeout, unmatched cache event code in counter register.\n");
0338         return 0;
0339     }
0340 
0341     v = fme_read_perf_cntr_reg(base + CACHE_CNTR0);
0342     count = FIELD_GET(CACHE_CNTR_EVNT_CNTR, v);
0343     v = fme_read_perf_cntr_reg(base + CACHE_CNTR1);
0344     count += FIELD_GET(CACHE_CNTR_EVNT_CNTR, v);
0345 
0346     return count;
0347 }
0348 
0349 static bool is_fabric_event_supported(struct fme_perf_priv *priv, u32 event,
0350                       u32 portid)
0351 {
0352     if (event > FAB_EVNT_MAX || !is_portid_root_or_port(portid))
0353         return false;
0354 
0355     if (priv->id == FME_FEATURE_ID_GLOBAL_DPERF &&
0356         (event == FAB_EVNT_PCIE1_RD || event == FAB_EVNT_UPI_RD ||
0357          event == FAB_EVNT_PCIE1_WR || event == FAB_EVNT_UPI_WR))
0358         return false;
0359 
0360     return true;
0361 }
0362 
0363 static int fabric_event_init(struct fme_perf_priv *priv, u32 event, u32 portid)
0364 {
0365     void __iomem *base = priv->ioaddr;
0366     int ret = 0;
0367     u64 v;
0368 
0369     if (!is_fabric_event_supported(priv, event, portid))
0370         return -EINVAL;
0371 
0372     /*
0373      * as fabric counter set only can be in either overall or port mode.
0374      * In overall mode, it counts overall data for FPGA, and in port mode,
0375      * it is configured to monitor on one individual port.
0376      *
0377      * so every time, a new event is initialized, driver checks
0378      * current working mode and if someone is using this counter set.
0379      */
0380     spin_lock(&priv->fab_lock);
0381     if (priv->fab_users && priv->fab_port_id != portid) {
0382         dev_dbg(priv->dev, "conflict fabric event monitoring mode.\n");
0383         ret = -EOPNOTSUPP;
0384         goto exit;
0385     }
0386 
0387     priv->fab_users++;
0388 
0389     /*
0390      * skip if current working mode matches, otherwise change the working
0391      * mode per input port_id, to monitor overall data or another port.
0392      */
0393     if (priv->fab_port_id == portid)
0394         goto exit;
0395 
0396     priv->fab_port_id = portid;
0397 
0398     v = readq(base + FAB_CTRL);
0399     v &= ~(FAB_PORT_FILTER | FAB_PORT_ID);
0400 
0401     if (is_portid_root(portid)) {
0402         v |= FIELD_PREP(FAB_PORT_FILTER, FAB_PORT_FILTER_DISABLE);
0403     } else {
0404         v |= FIELD_PREP(FAB_PORT_FILTER, FAB_PORT_FILTER_ENABLE);
0405         v |= FIELD_PREP(FAB_PORT_ID, portid);
0406     }
0407     writeq(v, base + FAB_CTRL);
0408 
0409 exit:
0410     spin_unlock(&priv->fab_lock);
0411     return ret;
0412 }
0413 
0414 static void fabric_event_destroy(struct fme_perf_priv *priv, u32 event,
0415                  u32 portid)
0416 {
0417     spin_lock(&priv->fab_lock);
0418     priv->fab_users--;
0419     spin_unlock(&priv->fab_lock);
0420 }
0421 
0422 static u64 fabric_read_event_counter(struct fme_perf_priv *priv, u32 event,
0423                      u32 portid)
0424 {
0425     void __iomem *base = priv->ioaddr;
0426     u64 v;
0427 
0428     v = readq(base + FAB_CTRL);
0429     v &= ~FAB_CTRL_EVNT;
0430     v |= FIELD_PREP(FAB_CTRL_EVNT, event);
0431     writeq(v, base + FAB_CTRL);
0432 
0433     if (readq_poll_timeout_atomic(base + FAB_CNTR, v,
0434                       FIELD_GET(FAB_CNTR_EVNT, v) == event,
0435                       1, PERF_TIMEOUT)) {
0436         dev_err(priv->dev, "timeout, unmatched fab event code in counter register.\n");
0437         return 0;
0438     }
0439 
0440     v = fme_read_perf_cntr_reg(base + FAB_CNTR);
0441     return FIELD_GET(FAB_CNTR_EVNT_CNTR, v);
0442 }
0443 
0444 static int vtd_event_init(struct fme_perf_priv *priv, u32 event, u32 portid)
0445 {
0446     if (priv->id == FME_FEATURE_ID_GLOBAL_IPERF &&
0447         event <= VTD_EVNT_MAX && is_portid_port(portid))
0448         return 0;
0449 
0450     return -EINVAL;
0451 }
0452 
0453 static u64 vtd_read_event_counter(struct fme_perf_priv *priv, u32 event,
0454                   u32 portid)
0455 {
0456     void __iomem *base = priv->ioaddr;
0457     u64 v;
0458 
0459     event += (portid * (VTD_EVNT_MAX + 1));
0460 
0461     v = readq(base + VTD_CTRL);
0462     v &= ~VTD_CTRL_EVNT;
0463     v |= FIELD_PREP(VTD_CTRL_EVNT, event);
0464     writeq(v, base + VTD_CTRL);
0465 
0466     if (readq_poll_timeout_atomic(base + VTD_CNTR, v,
0467                       FIELD_GET(VTD_CNTR_EVNT, v) == event,
0468                       1, PERF_TIMEOUT)) {
0469         dev_err(priv->dev, "timeout, unmatched vtd event code in counter register.\n");
0470         return 0;
0471     }
0472 
0473     v = fme_read_perf_cntr_reg(base + VTD_CNTR);
0474     return FIELD_GET(VTD_CNTR_EVNT_CNTR, v);
0475 }
0476 
0477 static int vtd_sip_event_init(struct fme_perf_priv *priv, u32 event, u32 portid)
0478 {
0479     if (priv->id == FME_FEATURE_ID_GLOBAL_IPERF &&
0480         event <= VTD_SIP_EVNT_MAX && is_portid_root(portid))
0481         return 0;
0482 
0483     return -EINVAL;
0484 }
0485 
0486 static u64 vtd_sip_read_event_counter(struct fme_perf_priv *priv, u32 event,
0487                       u32 portid)
0488 {
0489     void __iomem *base = priv->ioaddr;
0490     u64 v;
0491 
0492     v = readq(base + VTD_SIP_CTRL);
0493     v &= ~VTD_SIP_CTRL_EVNT;
0494     v |= FIELD_PREP(VTD_SIP_CTRL_EVNT, event);
0495     writeq(v, base + VTD_SIP_CTRL);
0496 
0497     if (readq_poll_timeout_atomic(base + VTD_SIP_CNTR, v,
0498                       FIELD_GET(VTD_SIP_CNTR_EVNT, v) == event,
0499                       1, PERF_TIMEOUT)) {
0500         dev_err(priv->dev, "timeout, unmatched vtd sip event code in counter register\n");
0501         return 0;
0502     }
0503 
0504     v = fme_read_perf_cntr_reg(base + VTD_SIP_CNTR);
0505     return FIELD_GET(VTD_SIP_CNTR_EVNT_CNTR, v);
0506 }
0507 
0508 static struct fme_perf_event_ops fme_perf_event_ops[] = {
0509     [FME_EVTYPE_BASIC]  = {.event_init = basic_event_init,
0510                    .read_counter = basic_read_event_counter,},
0511     [FME_EVTYPE_CACHE]  = {.event_init = cache_event_init,
0512                    .read_counter = cache_read_event_counter,},
0513     [FME_EVTYPE_FABRIC] = {.event_init = fabric_event_init,
0514                    .event_destroy = fabric_event_destroy,
0515                    .read_counter = fabric_read_event_counter,},
0516     [FME_EVTYPE_VTD]    = {.event_init = vtd_event_init,
0517                    .read_counter = vtd_read_event_counter,},
0518     [FME_EVTYPE_VTD_SIP]    = {.event_init = vtd_sip_event_init,
0519                    .read_counter = vtd_sip_read_event_counter,},
0520 };
0521 
0522 static ssize_t fme_perf_event_show(struct device *dev,
0523                    struct device_attribute *attr, char *buf)
0524 {
0525     struct dev_ext_attribute *eattr;
0526     unsigned long config;
0527     char *ptr = buf;
0528 
0529     eattr = container_of(attr, struct dev_ext_attribute, attr);
0530     config = (unsigned long)eattr->var;
0531 
0532     ptr += sprintf(ptr, "event=0x%02x", (unsigned int)get_event(config));
0533     ptr += sprintf(ptr, ",evtype=0x%02x", (unsigned int)get_evtype(config));
0534 
0535     if (is_portid_root(get_portid(config)))
0536         ptr += sprintf(ptr, ",portid=0x%02x\n", FME_PORTID_ROOT);
0537     else
0538         ptr += sprintf(ptr, ",portid=?\n");
0539 
0540     return (ssize_t)(ptr - buf);
0541 }
0542 
0543 #define FME_EVENT_ATTR(_name) \
0544     __ATTR(_name, 0444, fme_perf_event_show, NULL)
0545 
0546 #define FME_PORT_EVENT_CONFIG(_event, _type)                \
0547     (void *)((((_event) << FME_EVENT_SHIFT) & FME_EVENT_MASK) | \
0548         (((_type) << FME_EVTYPE_SHIFT) & FME_EVTYPE_MASK))
0549 
0550 #define FME_EVENT_CONFIG(_event, _type)                 \
0551     (void *)((((_event) << FME_EVENT_SHIFT) & FME_EVENT_MASK) | \
0552         (((_type) << FME_EVTYPE_SHIFT) & FME_EVTYPE_MASK) | \
0553         (FME_PORTID_ROOT << FME_PORTID_SHIFT))
0554 
0555 /* FME Perf Basic Events */
0556 #define FME_EVENT_BASIC(_name, _event)                  \
0557 static struct dev_ext_attribute fme_perf_event_##_name = {      \
0558     .attr = FME_EVENT_ATTR(_name),                  \
0559     .var = FME_EVENT_CONFIG(_event, FME_EVTYPE_BASIC),      \
0560 }
0561 
0562 FME_EVENT_BASIC(clock, BASIC_EVNT_CLK);
0563 
0564 static struct attribute *fme_perf_basic_events_attrs[] = {
0565     &fme_perf_event_clock.attr.attr,
0566     NULL,
0567 };
0568 
0569 static const struct attribute_group fme_perf_basic_events_group = {
0570     .name = "events",
0571     .attrs = fme_perf_basic_events_attrs,
0572 };
0573 
0574 /* FME Perf Cache Events */
0575 #define FME_EVENT_CACHE(_name, _event)                  \
0576 static struct dev_ext_attribute fme_perf_event_cache_##_name = {    \
0577     .attr = FME_EVENT_ATTR(cache_##_name),              \
0578     .var = FME_EVENT_CONFIG(_event, FME_EVTYPE_CACHE),      \
0579 }
0580 
0581 FME_EVENT_CACHE(read_hit,     CACHE_EVNT_RD_HIT);
0582 FME_EVENT_CACHE(read_miss,    CACHE_EVNT_RD_MISS);
0583 FME_EVENT_CACHE(write_hit,    CACHE_EVNT_WR_HIT);
0584 FME_EVENT_CACHE(write_miss,   CACHE_EVNT_WR_MISS);
0585 FME_EVENT_CACHE(hold_request, CACHE_EVNT_HOLD_REQ);
0586 FME_EVENT_CACHE(tx_req_stall, CACHE_EVNT_TX_REQ_STALL);
0587 FME_EVENT_CACHE(rx_req_stall, CACHE_EVNT_RX_REQ_STALL);
0588 FME_EVENT_CACHE(eviction,     CACHE_EVNT_EVICTIONS);
0589 FME_EVENT_CACHE(data_write_port_contention, CACHE_EVNT_DATA_WR_PORT_CONTEN);
0590 FME_EVENT_CACHE(tag_write_port_contention,  CACHE_EVNT_TAG_WR_PORT_CONTEN);
0591 
0592 static struct attribute *fme_perf_cache_events_attrs[] = {
0593     &fme_perf_event_cache_read_hit.attr.attr,
0594     &fme_perf_event_cache_read_miss.attr.attr,
0595     &fme_perf_event_cache_write_hit.attr.attr,
0596     &fme_perf_event_cache_write_miss.attr.attr,
0597     &fme_perf_event_cache_hold_request.attr.attr,
0598     &fme_perf_event_cache_tx_req_stall.attr.attr,
0599     &fme_perf_event_cache_rx_req_stall.attr.attr,
0600     &fme_perf_event_cache_eviction.attr.attr,
0601     &fme_perf_event_cache_data_write_port_contention.attr.attr,
0602     &fme_perf_event_cache_tag_write_port_contention.attr.attr,
0603     NULL,
0604 };
0605 
0606 static umode_t fme_perf_events_visible(struct kobject *kobj,
0607                        struct attribute *attr, int n)
0608 {
0609     struct pmu *pmu = dev_get_drvdata(kobj_to_dev(kobj));
0610     struct fme_perf_priv *priv = to_fme_perf_priv(pmu);
0611 
0612     return (priv->id == FME_FEATURE_ID_GLOBAL_IPERF) ? attr->mode : 0;
0613 }
0614 
0615 static const struct attribute_group fme_perf_cache_events_group = {
0616     .name = "events",
0617     .attrs = fme_perf_cache_events_attrs,
0618     .is_visible = fme_perf_events_visible,
0619 };
0620 
0621 /* FME Perf Fabric Events */
0622 #define FME_EVENT_FABRIC(_name, _event)                 \
0623 static struct dev_ext_attribute fme_perf_event_fab_##_name = {      \
0624     .attr = FME_EVENT_ATTR(fab_##_name),                \
0625     .var = FME_EVENT_CONFIG(_event, FME_EVTYPE_FABRIC),     \
0626 }
0627 
0628 #define FME_EVENT_FABRIC_PORT(_name, _event)                \
0629 static struct dev_ext_attribute fme_perf_event_fab_port_##_name = { \
0630     .attr = FME_EVENT_ATTR(fab_port_##_name),           \
0631     .var = FME_PORT_EVENT_CONFIG(_event, FME_EVTYPE_FABRIC),    \
0632 }
0633 
0634 FME_EVENT_FABRIC(pcie0_read,  FAB_EVNT_PCIE0_RD);
0635 FME_EVENT_FABRIC(pcie0_write, FAB_EVNT_PCIE0_WR);
0636 FME_EVENT_FABRIC(pcie1_read,  FAB_EVNT_PCIE1_RD);
0637 FME_EVENT_FABRIC(pcie1_write, FAB_EVNT_PCIE1_WR);
0638 FME_EVENT_FABRIC(upi_read,    FAB_EVNT_UPI_RD);
0639 FME_EVENT_FABRIC(upi_write,   FAB_EVNT_UPI_WR);
0640 FME_EVENT_FABRIC(mmio_read,   FAB_EVNT_MMIO_RD);
0641 FME_EVENT_FABRIC(mmio_write,  FAB_EVNT_MMIO_WR);
0642 
0643 FME_EVENT_FABRIC_PORT(pcie0_read,  FAB_EVNT_PCIE0_RD);
0644 FME_EVENT_FABRIC_PORT(pcie0_write, FAB_EVNT_PCIE0_WR);
0645 FME_EVENT_FABRIC_PORT(pcie1_read,  FAB_EVNT_PCIE1_RD);
0646 FME_EVENT_FABRIC_PORT(pcie1_write, FAB_EVNT_PCIE1_WR);
0647 FME_EVENT_FABRIC_PORT(upi_read,    FAB_EVNT_UPI_RD);
0648 FME_EVENT_FABRIC_PORT(upi_write,   FAB_EVNT_UPI_WR);
0649 FME_EVENT_FABRIC_PORT(mmio_read,   FAB_EVNT_MMIO_RD);
0650 FME_EVENT_FABRIC_PORT(mmio_write,  FAB_EVNT_MMIO_WR);
0651 
0652 static struct attribute *fme_perf_fabric_events_attrs[] = {
0653     &fme_perf_event_fab_pcie0_read.attr.attr,
0654     &fme_perf_event_fab_pcie0_write.attr.attr,
0655     &fme_perf_event_fab_pcie1_read.attr.attr,
0656     &fme_perf_event_fab_pcie1_write.attr.attr,
0657     &fme_perf_event_fab_upi_read.attr.attr,
0658     &fme_perf_event_fab_upi_write.attr.attr,
0659     &fme_perf_event_fab_mmio_read.attr.attr,
0660     &fme_perf_event_fab_mmio_write.attr.attr,
0661     &fme_perf_event_fab_port_pcie0_read.attr.attr,
0662     &fme_perf_event_fab_port_pcie0_write.attr.attr,
0663     &fme_perf_event_fab_port_pcie1_read.attr.attr,
0664     &fme_perf_event_fab_port_pcie1_write.attr.attr,
0665     &fme_perf_event_fab_port_upi_read.attr.attr,
0666     &fme_perf_event_fab_port_upi_write.attr.attr,
0667     &fme_perf_event_fab_port_mmio_read.attr.attr,
0668     &fme_perf_event_fab_port_mmio_write.attr.attr,
0669     NULL,
0670 };
0671 
0672 static umode_t fme_perf_fabric_events_visible(struct kobject *kobj,
0673                           struct attribute *attr, int n)
0674 {
0675     struct pmu *pmu = dev_get_drvdata(kobj_to_dev(kobj));
0676     struct fme_perf_priv *priv = to_fme_perf_priv(pmu);
0677     struct dev_ext_attribute *eattr;
0678     unsigned long var;
0679 
0680     eattr = container_of(attr, struct dev_ext_attribute, attr.attr);
0681     var = (unsigned long)eattr->var;
0682 
0683     if (is_fabric_event_supported(priv, get_event(var), get_portid(var)))
0684         return attr->mode;
0685 
0686     return 0;
0687 }
0688 
0689 static const struct attribute_group fme_perf_fabric_events_group = {
0690     .name = "events",
0691     .attrs = fme_perf_fabric_events_attrs,
0692     .is_visible = fme_perf_fabric_events_visible,
0693 };
0694 
0695 /* FME Perf VTD Events */
0696 #define FME_EVENT_VTD_PORT(_name, _event)               \
0697 static struct dev_ext_attribute fme_perf_event_vtd_port_##_name = { \
0698     .attr = FME_EVENT_ATTR(vtd_port_##_name),           \
0699     .var = FME_PORT_EVENT_CONFIG(_event, FME_EVTYPE_VTD),       \
0700 }
0701 
0702 FME_EVENT_VTD_PORT(read_transaction,  VTD_EVNT_AFU_MEM_RD_TRANS);
0703 FME_EVENT_VTD_PORT(write_transaction, VTD_EVNT_AFU_MEM_WR_TRANS);
0704 FME_EVENT_VTD_PORT(devtlb_read_hit,   VTD_EVNT_AFU_DEVTLB_RD_HIT);
0705 FME_EVENT_VTD_PORT(devtlb_write_hit,  VTD_EVNT_AFU_DEVTLB_WR_HIT);
0706 FME_EVENT_VTD_PORT(devtlb_4k_fill,    VTD_EVNT_DEVTLB_4K_FILL);
0707 FME_EVENT_VTD_PORT(devtlb_2m_fill,    VTD_EVNT_DEVTLB_2M_FILL);
0708 FME_EVENT_VTD_PORT(devtlb_1g_fill,    VTD_EVNT_DEVTLB_1G_FILL);
0709 
0710 static struct attribute *fme_perf_vtd_events_attrs[] = {
0711     &fme_perf_event_vtd_port_read_transaction.attr.attr,
0712     &fme_perf_event_vtd_port_write_transaction.attr.attr,
0713     &fme_perf_event_vtd_port_devtlb_read_hit.attr.attr,
0714     &fme_perf_event_vtd_port_devtlb_write_hit.attr.attr,
0715     &fme_perf_event_vtd_port_devtlb_4k_fill.attr.attr,
0716     &fme_perf_event_vtd_port_devtlb_2m_fill.attr.attr,
0717     &fme_perf_event_vtd_port_devtlb_1g_fill.attr.attr,
0718     NULL,
0719 };
0720 
0721 static const struct attribute_group fme_perf_vtd_events_group = {
0722     .name = "events",
0723     .attrs = fme_perf_vtd_events_attrs,
0724     .is_visible = fme_perf_events_visible,
0725 };
0726 
0727 /* FME Perf VTD SIP Events */
0728 #define FME_EVENT_VTD_SIP(_name, _event)                \
0729 static struct dev_ext_attribute fme_perf_event_vtd_sip_##_name = {  \
0730     .attr = FME_EVENT_ATTR(vtd_sip_##_name),            \
0731     .var = FME_EVENT_CONFIG(_event, FME_EVTYPE_VTD_SIP),        \
0732 }
0733 
0734 FME_EVENT_VTD_SIP(iotlb_4k_hit,  VTD_SIP_EVNT_IOTLB_4K_HIT);
0735 FME_EVENT_VTD_SIP(iotlb_2m_hit,  VTD_SIP_EVNT_IOTLB_2M_HIT);
0736 FME_EVENT_VTD_SIP(iotlb_1g_hit,  VTD_SIP_EVNT_IOTLB_1G_HIT);
0737 FME_EVENT_VTD_SIP(slpwc_l3_hit,  VTD_SIP_EVNT_SLPWC_L3_HIT);
0738 FME_EVENT_VTD_SIP(slpwc_l4_hit,  VTD_SIP_EVNT_SLPWC_L4_HIT);
0739 FME_EVENT_VTD_SIP(rcc_hit,       VTD_SIP_EVNT_RCC_HIT);
0740 FME_EVENT_VTD_SIP(iotlb_4k_miss, VTD_SIP_EVNT_IOTLB_4K_MISS);
0741 FME_EVENT_VTD_SIP(iotlb_2m_miss, VTD_SIP_EVNT_IOTLB_2M_MISS);
0742 FME_EVENT_VTD_SIP(iotlb_1g_miss, VTD_SIP_EVNT_IOTLB_1G_MISS);
0743 FME_EVENT_VTD_SIP(slpwc_l3_miss, VTD_SIP_EVNT_SLPWC_L3_MISS);
0744 FME_EVENT_VTD_SIP(slpwc_l4_miss, VTD_SIP_EVNT_SLPWC_L4_MISS);
0745 FME_EVENT_VTD_SIP(rcc_miss,      VTD_SIP_EVNT_RCC_MISS);
0746 
0747 static struct attribute *fme_perf_vtd_sip_events_attrs[] = {
0748     &fme_perf_event_vtd_sip_iotlb_4k_hit.attr.attr,
0749     &fme_perf_event_vtd_sip_iotlb_2m_hit.attr.attr,
0750     &fme_perf_event_vtd_sip_iotlb_1g_hit.attr.attr,
0751     &fme_perf_event_vtd_sip_slpwc_l3_hit.attr.attr,
0752     &fme_perf_event_vtd_sip_slpwc_l4_hit.attr.attr,
0753     &fme_perf_event_vtd_sip_rcc_hit.attr.attr,
0754     &fme_perf_event_vtd_sip_iotlb_4k_miss.attr.attr,
0755     &fme_perf_event_vtd_sip_iotlb_2m_miss.attr.attr,
0756     &fme_perf_event_vtd_sip_iotlb_1g_miss.attr.attr,
0757     &fme_perf_event_vtd_sip_slpwc_l3_miss.attr.attr,
0758     &fme_perf_event_vtd_sip_slpwc_l4_miss.attr.attr,
0759     &fme_perf_event_vtd_sip_rcc_miss.attr.attr,
0760     NULL,
0761 };
0762 
0763 static const struct attribute_group fme_perf_vtd_sip_events_group = {
0764     .name = "events",
0765     .attrs = fme_perf_vtd_sip_events_attrs,
0766     .is_visible = fme_perf_events_visible,
0767 };
0768 
0769 static const struct attribute_group *fme_perf_events_groups[] = {
0770     &fme_perf_basic_events_group,
0771     &fme_perf_cache_events_group,
0772     &fme_perf_fabric_events_group,
0773     &fme_perf_vtd_events_group,
0774     &fme_perf_vtd_sip_events_group,
0775     NULL,
0776 };
0777 
0778 static struct fme_perf_event_ops *get_event_ops(u32 evtype)
0779 {
0780     if (evtype > FME_EVTYPE_MAX)
0781         return NULL;
0782 
0783     return &fme_perf_event_ops[evtype];
0784 }
0785 
0786 static void fme_perf_event_destroy(struct perf_event *event)
0787 {
0788     struct fme_perf_event_ops *ops = get_event_ops(event->hw.event_base);
0789     struct fme_perf_priv *priv = to_fme_perf_priv(event->pmu);
0790 
0791     if (ops->event_destroy)
0792         ops->event_destroy(priv, event->hw.idx, event->hw.config_base);
0793 }
0794 
0795 static int fme_perf_event_init(struct perf_event *event)
0796 {
0797     struct fme_perf_priv *priv = to_fme_perf_priv(event->pmu);
0798     struct hw_perf_event *hwc = &event->hw;
0799     struct fme_perf_event_ops *ops;
0800     u32 eventid, evtype, portid;
0801 
0802     /* test the event attr type check for PMU enumeration */
0803     if (event->attr.type != event->pmu->type)
0804         return -ENOENT;
0805 
0806     /*
0807      * fme counters are shared across all cores.
0808      * Therefore, it does not support per-process mode.
0809      * Also, it does not support event sampling mode.
0810      */
0811     if (is_sampling_event(event) || event->attach_state & PERF_ATTACH_TASK)
0812         return -EINVAL;
0813 
0814     if (event->cpu < 0)
0815         return -EINVAL;
0816 
0817     if (event->cpu != priv->cpu)
0818         return -EINVAL;
0819 
0820     eventid = get_event(event->attr.config);
0821     portid = get_portid(event->attr.config);
0822     evtype = get_evtype(event->attr.config);
0823     if (evtype > FME_EVTYPE_MAX)
0824         return -EINVAL;
0825 
0826     hwc->event_base = evtype;
0827     hwc->idx = (int)eventid;
0828     hwc->config_base = portid;
0829 
0830     event->destroy = fme_perf_event_destroy;
0831 
0832     dev_dbg(priv->dev, "%s event=0x%x, evtype=0x%x, portid=0x%x,\n",
0833         __func__, eventid, evtype, portid);
0834 
0835     ops = get_event_ops(evtype);
0836     if (ops->event_init)
0837         return ops->event_init(priv, eventid, portid);
0838 
0839     return 0;
0840 }
0841 
0842 static void fme_perf_event_update(struct perf_event *event)
0843 {
0844     struct fme_perf_event_ops *ops = get_event_ops(event->hw.event_base);
0845     struct fme_perf_priv *priv = to_fme_perf_priv(event->pmu);
0846     struct hw_perf_event *hwc = &event->hw;
0847     u64 now, prev, delta;
0848 
0849     now = ops->read_counter(priv, (u32)hwc->idx, hwc->config_base);
0850     prev = local64_read(&hwc->prev_count);
0851     delta = now - prev;
0852 
0853     local64_add(delta, &event->count);
0854 }
0855 
0856 static void fme_perf_event_start(struct perf_event *event, int flags)
0857 {
0858     struct fme_perf_event_ops *ops = get_event_ops(event->hw.event_base);
0859     struct fme_perf_priv *priv = to_fme_perf_priv(event->pmu);
0860     struct hw_perf_event *hwc = &event->hw;
0861     u64 count;
0862 
0863     count = ops->read_counter(priv, (u32)hwc->idx, hwc->config_base);
0864     local64_set(&hwc->prev_count, count);
0865 }
0866 
0867 static void fme_perf_event_stop(struct perf_event *event, int flags)
0868 {
0869     fme_perf_event_update(event);
0870 }
0871 
0872 static int fme_perf_event_add(struct perf_event *event, int flags)
0873 {
0874     if (flags & PERF_EF_START)
0875         fme_perf_event_start(event, flags);
0876 
0877     return 0;
0878 }
0879 
0880 static void fme_perf_event_del(struct perf_event *event, int flags)
0881 {
0882     fme_perf_event_stop(event, PERF_EF_UPDATE);
0883 }
0884 
0885 static void fme_perf_event_read(struct perf_event *event)
0886 {
0887     fme_perf_event_update(event);
0888 }
0889 
0890 static void fme_perf_setup_hardware(struct fme_perf_priv *priv)
0891 {
0892     void __iomem *base = priv->ioaddr;
0893     u64 v;
0894 
0895     /* read and save current working mode for fabric counters */
0896     v = readq(base + FAB_CTRL);
0897 
0898     if (FIELD_GET(FAB_PORT_FILTER, v) == FAB_PORT_FILTER_DISABLE)
0899         priv->fab_port_id = FME_PORTID_ROOT;
0900     else
0901         priv->fab_port_id = FIELD_GET(FAB_PORT_ID, v);
0902 }
0903 
0904 static int fme_perf_pmu_register(struct platform_device *pdev,
0905                  struct fme_perf_priv *priv)
0906 {
0907     struct pmu *pmu = &priv->pmu;
0908     char *name;
0909     int ret;
0910 
0911     spin_lock_init(&priv->fab_lock);
0912 
0913     fme_perf_setup_hardware(priv);
0914 
0915     pmu->task_ctx_nr =  perf_invalid_context;
0916     pmu->attr_groups =  fme_perf_groups;
0917     pmu->attr_update =  fme_perf_events_groups;
0918     pmu->event_init =   fme_perf_event_init;
0919     pmu->add =      fme_perf_event_add;
0920     pmu->del =      fme_perf_event_del;
0921     pmu->start =        fme_perf_event_start;
0922     pmu->stop =     fme_perf_event_stop;
0923     pmu->read =     fme_perf_event_read;
0924     pmu->capabilities = PERF_PMU_CAP_NO_INTERRUPT |
0925                 PERF_PMU_CAP_NO_EXCLUDE;
0926 
0927     name = devm_kasprintf(priv->dev, GFP_KERNEL, "dfl_fme%d", pdev->id);
0928 
0929     ret = perf_pmu_register(pmu, name, -1);
0930     if (ret)
0931         return ret;
0932 
0933     return 0;
0934 }
0935 
0936 static void fme_perf_pmu_unregister(struct fme_perf_priv *priv)
0937 {
0938     perf_pmu_unregister(&priv->pmu);
0939 }
0940 
0941 static int fme_perf_offline_cpu(unsigned int cpu, struct hlist_node *node)
0942 {
0943     struct fme_perf_priv *priv;
0944     int target;
0945 
0946     priv = hlist_entry_safe(node, struct fme_perf_priv, node);
0947 
0948     if (cpu != priv->cpu)
0949         return 0;
0950 
0951     target = cpumask_any_but(cpu_online_mask, cpu);
0952     if (target >= nr_cpu_ids)
0953         return 0;
0954 
0955     priv->cpu = target;
0956     perf_pmu_migrate_context(&priv->pmu, cpu, target);
0957 
0958     return 0;
0959 }
0960 
0961 static int fme_perf_init(struct platform_device *pdev,
0962              struct dfl_feature *feature)
0963 {
0964     struct fme_perf_priv *priv;
0965     int ret;
0966 
0967     priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0968     if (!priv)
0969         return -ENOMEM;
0970 
0971     priv->dev = &pdev->dev;
0972     priv->ioaddr = feature->ioaddr;
0973     priv->id = feature->id;
0974     priv->cpu = raw_smp_processor_id();
0975 
0976     ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN,
0977                       "perf/fpga/dfl_fme:online",
0978                       NULL, fme_perf_offline_cpu);
0979     if (ret < 0)
0980         return ret;
0981 
0982     priv->cpuhp_state = ret;
0983 
0984     /* Register the pmu instance for cpu hotplug */
0985     ret = cpuhp_state_add_instance_nocalls(priv->cpuhp_state, &priv->node);
0986     if (ret)
0987         goto cpuhp_instance_err;
0988 
0989     ret = fme_perf_pmu_register(pdev, priv);
0990     if (ret)
0991         goto pmu_register_err;
0992 
0993     feature->priv = priv;
0994     return 0;
0995 
0996 pmu_register_err:
0997     cpuhp_state_remove_instance_nocalls(priv->cpuhp_state, &priv->node);
0998 cpuhp_instance_err:
0999     cpuhp_remove_multi_state(priv->cpuhp_state);
1000     return ret;
1001 }
1002 
1003 static void fme_perf_uinit(struct platform_device *pdev,
1004                struct dfl_feature *feature)
1005 {
1006     struct fme_perf_priv *priv = feature->priv;
1007 
1008     fme_perf_pmu_unregister(priv);
1009     cpuhp_state_remove_instance_nocalls(priv->cpuhp_state, &priv->node);
1010     cpuhp_remove_multi_state(priv->cpuhp_state);
1011 }
1012 
1013 const struct dfl_feature_id fme_perf_id_table[] = {
1014     {.id = FME_FEATURE_ID_GLOBAL_IPERF,},
1015     {.id = FME_FEATURE_ID_GLOBAL_DPERF,},
1016     {0,}
1017 };
1018 
1019 const struct dfl_feature_ops fme_perf_ops = {
1020     .init = fme_perf_init,
1021     .uinit = fme_perf_uinit,
1022 };