linux/drivers/perf/thunderx2_pmu.c

// SPDX-License-Identifier: GPL-2.0
/*
 * CAVIUM THUNDERX2 SoC PMU UNCORE
 * Copyright (C) 2018 Cavium Inc.
 * Author: Ganapatrao Kulkarni <[email protected]>
 */

#include <linux/acpi.h>
#include <linux/cpuhotplug.h>
#include <linux/perf_event.h>
#include <linux/platform_device.h>

/* Each ThunderX2(TX2) Socket has a L3C and DMC UNCORE PMU device.
 * Each UNCORE PMU device consists of 4 independent programmable counters.
 * Counters are 32 bit and do not support overflow interrupt,
 * they need to be sampled before overflow(i.e, at every 2 seconds).
 */

#define TX2_PMU_DMC_L3C_MAX_COUNTERS
#define TX2_PMU_CCPI2_MAX_COUNTERS
#define TX2_PMU_MAX_COUNTERS


#define TX2_PMU_DMC_CHANNELS
#define TX2_PMU_L3_TILES

#define TX2_PMU_HRTIMER_INTERVAL
#define GET_EVENTID(ev, mask)
#define GET_COUNTERID(ev, mask)
 /* 1 byte per counter(4 counters).
  * Event id is encoded in bits [5:1] of a byte,
  */
#define DMC_EVENT_CFG(idx, val)

/* bits[3:0] to select counters, are indexed from 8 to 15. */
#define CCPI2_COUNTER_OFFSET

#define L3C_COUNTER_CTL
#define L3C_COUNTER_DATA
#define DMC_COUNTER_CTL
#define DMC_COUNTER_DATA

#define CCPI2_PERF_CTL
#define CCPI2_COUNTER_CTL
#define CCPI2_COUNTER_SEL
#define CCPI2_COUNTER_DATA_L
#define CCPI2_COUNTER_DATA_H

/* L3C event IDs */
#define L3_EVENT_READ_REQ
#define L3_EVENT_WRITEBACK_REQ
#define L3_EVENT_INV_N_WRITE_REQ
#define L3_EVENT_INV_REQ
#define L3_EVENT_EVICT_REQ
#define L3_EVENT_INV_N_WRITE_HIT
#define L3_EVENT_INV_HIT
#define L3_EVENT_READ_HIT
#define L3_EVENT_MAX

/* DMC event IDs */
#define DMC_EVENT_COUNT_CYCLES
#define DMC_EVENT_WRITE_TXNS
#define DMC_EVENT_DATA_TRANSFERS
#define DMC_EVENT_READ_TXNS
#define DMC_EVENT_MAX

#define CCPI2_EVENT_REQ_PKT_SENT
#define CCPI2_EVENT_SNOOP_PKT_SENT
#define CCPI2_EVENT_DATA_PKT_SENT
#define CCPI2_EVENT_GIC_PKT_SENT
#define CCPI2_EVENT_MAX

#define CCPI2_PERF_CTL_ENABLE
#define CCPI2_PERF_CTL_START
#define CCPI2_PERF_CTL_RESET
#define CCPI2_EVENT_LEVEL_RISING_EDGE
#define CCPI2_EVENT_TYPE_EDGE_SENSITIVE

enum tx2_uncore_type {};

/*
 * Each socket has 3 uncore devices associated with a PMU. The DMC and
 * L3C have 4 32-bit counters and the CCPI2 has 8 64-bit counters.
 */
struct tx2_uncore_pmu {};

static LIST_HEAD(tx2_pmus);

static inline struct tx2_uncore_pmu *pmu_to_tx2_pmu(struct pmu *pmu)
{}

#define TX2_PMU_FORMAT_ATTR(_var, _name, _format)

TX2_PMU_FORMAT_ATTR();
TX2_PMU_FORMAT_ATTR();

static struct attribute *l3c_pmu_format_attrs[] =;

static struct attribute *dmc_pmu_format_attrs[] =;

static struct attribute *ccpi2_pmu_format_attrs[] =;

static const struct attribute_group l3c_pmu_format_attr_group =;

static const struct attribute_group dmc_pmu_format_attr_group =;

static const struct attribute_group ccpi2_pmu_format_attr_group =;

/*
 * sysfs event attributes
 */
static ssize_t tx2_pmu_event_show(struct device *dev,
				    struct device_attribute *attr, char *buf)
{}

#define TX2_EVENT_ATTR(name, config)

TX2_EVENT_ATTR(read_request, L3_EVENT_READ_REQ);
TX2_EVENT_ATTR(writeback_request, L3_EVENT_WRITEBACK_REQ);
TX2_EVENT_ATTR(inv_nwrite_request, L3_EVENT_INV_N_WRITE_REQ);
TX2_EVENT_ATTR(inv_request, L3_EVENT_INV_REQ);
TX2_EVENT_ATTR(evict_request, L3_EVENT_EVICT_REQ);
TX2_EVENT_ATTR(inv_nwrite_hit, L3_EVENT_INV_N_WRITE_HIT);
TX2_EVENT_ATTR(inv_hit, L3_EVENT_INV_HIT);
TX2_EVENT_ATTR(read_hit, L3_EVENT_READ_HIT);

static struct attribute *l3c_pmu_events_attrs[] =;

TX2_EVENT_ATTR(cnt_cycles, DMC_EVENT_COUNT_CYCLES);
TX2_EVENT_ATTR(write_txns, DMC_EVENT_WRITE_TXNS);
TX2_EVENT_ATTR(data_transfers, DMC_EVENT_DATA_TRANSFERS);
TX2_EVENT_ATTR(read_txns, DMC_EVENT_READ_TXNS);

static struct attribute *dmc_pmu_events_attrs[] =;

TX2_EVENT_ATTR(req_pktsent, CCPI2_EVENT_REQ_PKT_SENT);
TX2_EVENT_ATTR(snoop_pktsent, CCPI2_EVENT_SNOOP_PKT_SENT);
TX2_EVENT_ATTR(data_pktsent, CCPI2_EVENT_DATA_PKT_SENT);
TX2_EVENT_ATTR(gic_pktsent, CCPI2_EVENT_GIC_PKT_SENT);

static struct attribute *ccpi2_pmu_events_attrs[] =;

static const struct attribute_group l3c_pmu_events_attr_group =;

static const struct attribute_group dmc_pmu_events_attr_group =;

static const struct attribute_group ccpi2_pmu_events_attr_group =;

/*
 * sysfs cpumask attributes
 */
static ssize_t cpumask_show(struct device *dev, struct device_attribute *attr,
		char *buf)
{}
static DEVICE_ATTR_RO(cpumask);

static struct attribute *tx2_pmu_cpumask_attrs[] =;

static const struct attribute_group pmu_cpumask_attr_group =;

/*
 * Per PMU device attribute groups
 */
static const struct attribute_group *l3c_pmu_attr_groups[] =;

static const struct attribute_group *dmc_pmu_attr_groups[] =;

static const struct attribute_group *ccpi2_pmu_attr_groups[] =;

static inline u32 reg_readl(unsigned long addr)
{}

static inline void reg_writel(u32 val, unsigned long addr)
{}

static int alloc_counter(struct tx2_uncore_pmu *tx2_pmu)
{}

static inline void free_counter(struct tx2_uncore_pmu *tx2_pmu, int counter)
{}

static void init_cntr_base_l3c(struct perf_event *event,
		struct tx2_uncore_pmu *tx2_pmu)
{}

static void init_cntr_base_dmc(struct perf_event *event,
		struct tx2_uncore_pmu *tx2_pmu)
{}

static void init_cntr_base_ccpi2(struct perf_event *event,
		struct tx2_uncore_pmu *tx2_pmu)
{}

static void uncore_start_event_l3c(struct perf_event *event, int flags)
{}

static inline void uncore_stop_event_l3c(struct perf_event *event)
{}

static void uncore_start_event_dmc(struct perf_event *event, int flags)
{}

static void uncore_stop_event_dmc(struct perf_event *event)
{}

static void uncore_start_event_ccpi2(struct perf_event *event, int flags)
{}

static void uncore_stop_event_ccpi2(struct perf_event *event)
{}

static void tx2_uncore_event_update(struct perf_event *event)
{}

static enum tx2_uncore_type get_tx2_pmu_type(struct acpi_device *adev)
{}

static bool tx2_uncore_validate_event(struct pmu *pmu,
				  struct perf_event *event, int *counters)
{}

/*
 * Make sure the group of events can be scheduled at once
 * on the PMU.
 */
static bool tx2_uncore_validate_event_group(struct perf_event *event,
		int max_counters)
{}


static int tx2_uncore_event_init(struct perf_event *event)
{}

static void tx2_uncore_event_start(struct perf_event *event, int flags)
{}

static void tx2_uncore_event_stop(struct perf_event *event, int flags)
{}

static int tx2_uncore_event_add(struct perf_event *event, int flags)
{}

static void tx2_uncore_event_del(struct perf_event *event, int flags)
{}

static void tx2_uncore_event_read(struct perf_event *event)
{}

static enum hrtimer_restart tx2_hrtimer_callback(struct hrtimer *timer)
{}

static int tx2_uncore_pmu_register(
		struct tx2_uncore_pmu *tx2_pmu)
{}

static int tx2_uncore_pmu_add_dev(struct tx2_uncore_pmu *tx2_pmu)
{}

static struct tx2_uncore_pmu *tx2_uncore_pmu_init_dev(struct device *dev,
		acpi_handle handle, struct acpi_device *adev, u32 type)
{}

static acpi_status tx2_uncore_pmu_add(acpi_handle handle, u32 level,
				    void *data, void **return_value)
{}

static int tx2_uncore_pmu_online_cpu(unsigned int cpu,
		struct hlist_node *hpnode)
{}

static int tx2_uncore_pmu_offline_cpu(unsigned int cpu,
		struct hlist_node *hpnode)
{}

static const struct acpi_device_id tx2_uncore_acpi_match[] =;
MODULE_DEVICE_TABLE(acpi, tx2_uncore_acpi_match);

static int tx2_uncore_probe(struct platform_device *pdev)
{}

static void tx2_uncore_remove(struct platform_device *pdev)
{}

static struct platform_driver tx2_uncore_driver =;

static int __init tx2_uncore_driver_init(void)
{}
module_init();

static void __exit tx2_uncore_driver_exit(void)
{}
module_exit(tx2_uncore_driver_exit);

MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_AUTHOR();